В чем преимущество использования блоков инициализации? - PullRequest
3 голосов
/ 12 декабря 2011

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

class SmallInit {
   static int x;
   int y;
   static { x = 7 ; } // static init block
   { y = 8; } // instance init block
}

Но в чем же особенное преимущество, когда мы можем сделать это следующим образом:

class SmallInit {
   static int x = 7;
   int y = 8;
}

Ответы [ 7 ]

7 голосов
/ 12 декабря 2011

Одна приятная вещь в блоках инициализации экземпляра состоит в том, что они делают возможным шаблон Double Brace Initialization .

Вместо этого:

Set<String> names = new HashSet<String>();
names.add("Peter");
names.add("Paul");
names.add("Mary");

Вы можете сделать это:

Set<String> names = new HashSet<String>() {{
    add("Peter");
    add("Paul");
    add("Mary");
}};

Первая фигурная скобка создает анонимный внутренний класс;второй запускает блок инициализатора экземпляра.(Обратите внимание, что это означает, что names является экземпляром анонимного подкласса из HashSet, но это часто не проблема. Это также означает, что этот шаблон работает только для неконечных классов.)

Это особенно полезно в разовых ситуациях, когда было бы удобно инициализировать объект как выражение.Например:

doSomethingToSet(new HashSet<String>() {{
    add("Peter");
    add("Paul");
    add("Mary");
}});
3 голосов
/ 12 декабря 2011

Я не вижу никаких особых преимуществ для статических блоков, которые просто содержат объявления переменных в одну строку.На самом деле, когда все, что вы делаете - это присваиваете значения переменным вашего класса или экземпляра, (на мой взгляд) труднее понять, что происходит.

Статические блоки и блоки экземпляровТем не менее, они пригодятся, когда у вас есть более сложные начальные состояния, которые необходимо создать.Вот пример, где используются и объявление, и статический блок:

static List<Sprocket> mySprockets = new ArrayList<Sprocket>();

static {
    mySprockets.add(new Sprocket("foo", 17));
    mySprockets.add(new Sprocket("bar", 8));
}
2 голосов
/ 12 декабря 2011

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

, например

private static Map foo = initFoo();

private static Map initFoo() {
  Map foo = new Map();
  foo.put("x", "y");
  foo.put("a", "b");
  return foo;
}

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

0 голосов
/ 12 декабря 2011

Я нашел лучший ответ здесь , не принятый ответ, а ответ Джона Скита.

И спасибо Xaerxess за размещение ссылки для этого ответа.

0 голосов
/ 12 декабря 2011
  1. Без инициализатора переменная будет инициализирована до 0 или ноль. Поэтому, если вы собираетесь установить что-то в конструктор к другому значению, вы фактически устанавливаете его дважды (один раз 0 или ноль, затем снова в конструкторе, что вы хотите). потеря производительности незначительна в подавляющем большинстве случаев ( исключением может быть математический класс, который вы используете в узком цикле, но даже это будет очень зависеть от того, что еще произойдет в этом цикле).
  2. Это может помочь с удобочитаемостью.
  3. Если вы вызываете виртуальный метод из конструктора, член данных производного класс, используемый в переопределенном виртуальном методе, будет иметь значение 0 или ноль в качестве значения если у него нет инициализатора. Я не на 100% это дело в Java, как это было какое-то время; Я знаю, что это в C #.
0 голосов
/ 12 декабря 2011

Преимуществом блока инициализации экземпляра может быть следующее:

Компилятор Java копирует блоки инициализатора в каждый конструктор. Следовательно, этот подход можно использовать для разделения блока кода между несколькими конструкторами.

Перейти здесь для хорошего обзора.

0 голосов
/ 12 декабря 2011

Особого преимущества нет, оно может помочь в удобочитаемости в некоторых случаях (обычно, когда вы объявляете более одного участника).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...