Использование инициализаторов по сравнению с конструкторами в Java

Вы читали это? Получение согласия кажется, что для предоставления постоянного согласия вам понадобится «Согласие администратора для внутренних приложений», чтобы вы не перенаправлялись каждый раз при истечении срока действия токена JWT.

Приветствия.

94
задан Andrew Tobilko 25 November 2017 в 11:19
поделиться

6 ответов

Статические инициализаторы полезны, как упоминалось выше, и я использую их таким же образом. Если у вас есть статическая переменная, которая должна быть инициализирована при загрузке класса, тогда стоит использовать статический инициализатор, тем более что он позволяет выполнить сложную инициализацию и при этом статическая переменная будет final . Это большая победа.

Я считаю, что "if (someStaticVar == null) // делать вещи" грязно и подвержено ошибкам. Если он инициализируется статически и объявляется финальным , то вы избегаете возможности того, чтобы он был нулевым .

Однако я запутался, когда сказал:

static / instance инициализаторы могут быть использованы для установки значения «final» статические переменные / переменные экземпляра, в то время как конструктор не может

Я предполагаю, что вы говорите и то и другое:

  • статические инициализаторы могут использоваться для установки значения «конечных» статических переменных, тогда как конструктор не может
  • инициализаторы экземпляра могут использоваться для установки значение «конечных» переменных экземпляра, тогда как конструктор не может

, и вы правы в первой точке, а во второй - неверны. Вы можете, например, сделать это:

class MyClass {
    private final int counter;
    public MyClass(final int counter) {
        this.counter = counter;
    }
}

Кроме того, когда много конструкторов совместно используется конструкторами, один из лучших способов справиться с этим - создать цепочку конструкторов, предоставляя значения по умолчанию. Это делает довольно ясным, что делается:

class MyClass {
    private final int counter;
    public MyClass() {
        this(0);
    }
    public MyClass(final int counter) {
        this.counter = counter;
    }
}
55
ответ дан 24 November 2019 в 06:06
поделиться

У анонимных внутренних классов не может быть конструктора (поскольку они анонимны), поэтому они вполне естественны для инициализаторов экземпляров.

54
ответ дан 24 November 2019 в 06:06
поделиться

Чаще всего я использую блоки статического инициализатора для настройки конечных статических данных, особенно коллекций. Например:

public class Deck {
  private final static List<String> SUITS;

  static {
    List<String> list = new ArrayList<String>();
    list.add("Clubs");
    list.add("Spades");
    list.add("Hearts");
    list.add("Diamonds");
    SUITS = Collections.unmodifiableList(list);
  }

  ...
}

Теперь этот пример может быть выполнен с одной строкой кода:

private final static List<String> SUITS =
  Collections.unmodifiableList(
    Arrays.asList("Clubs", "Spades", "Hearts", "Diamonds")
  );

, но статическая версия может быть намного лучше, особенно когда элементы не тривиальны для инициализации.

Наивная реализация также может не создавать неизменяемый список, что является потенциальной ошибкой. Вышесказанное создает неизменную структуру данных, которую вы можете с радостью вернуть из открытых методов и т. Д.

26
ответ дан 24 November 2019 в 06:06
поделиться

Просто добавлю к некоторым и без того отличным моментам. Статический инициализатор является потокобезопасным. Он выполняется при загрузке класса и, следовательно, упрощает инициализацию статических данных, чем использование конструктора, в котором вам потребуется синхронизированный блок для проверки инициализации статических данных, а затем их инициализация.

public class MyClass {

    static private Properties propTable;

    static
    {
        try 
        {
            propTable.load(new FileInputStream("/data/user.prop"));
        } 
        catch (Exception e) 
        {
            propTable.put("user", System.getProperty("user"));
            propTable.put("password", System.getProperty("password"));
        }
    }

против

public class MyClass 
{
    public MyClass()
    {
        synchronized (MyClass.class) 
        {
            if (propTable == null)
            {
                try 
                {
                    propTable.load(new FileInputStream("/data/user.prop"));
                } 
                catch (Exception e) 
                {
                    propTable.put("user", System.getProperty("user"));
                    propTable.put("password", System.getProperty("password"));
                }
            }
        }
    }

] Не забывайте, теперь вы должны синхронизироваться на уровне класса, а не на уровне экземпляра. Это влечет за собой затраты для каждого созданного экземпляра вместо единовременных затрат при загрузке класса. Плюс это некрасиво; -)

14
ответ дан 24 November 2019 в 06:06
поделиться

Статический инициализатор является эквивалентом конструктора в статическом контексте. Вы наверняка увидите это чаще, чем инициализатор экземпляра. Иногда вам нужно запустить код для настройки статической среды.

В общем случае, инициализатор экземпляра лучше всего подходит для анонимных внутренних классов. Взгляните на кулинарную книгу JMock , чтобы увидеть инновационный способ использовать ее, чтобы сделать код более читабельным.

Иногда, если у вас есть какая-то логика, сложная для цепочки между конструкторами (скажем, вы используете подклассы и вы Я не могу вызвать this (), потому что вам нужно вызвать super ()), вы можете избежать дублирования, выполняя обычные вещи в initalizer экземпляра. Инициализаторы экземпляров настолько редки, что для многих они являются неожиданным синтаксисом,

7
ответ дан 24 November 2019 в 06:06
поделиться

Как вы упомянули, во многих случаях это бесполезно, и, как и в случае с любым менее используемым синтаксисом, вы, вероятно, хотите избежать его, просто чтобы следующий человек, который смотрит на ваш код, не тратил 30 секунд, чтобы вытащить его из хранилищ.

С другой стороны, это единственный способ сделать несколько вещей (я думаю, что вы в значительной степени покрыли это).

В любом случае самих статических переменных следует несколько избегать - - не всегда, но если вы используете их много или много в одном классе, вы можете найти разные подходы, ваше будущее я вас поблагодарит.

3
ответ дан 24 November 2019 в 06:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: