Значение нового класса (...) {{...}} Инициализация
Что означает {{ ... }}
значение блока в следующем коде?
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
Ответы
Ответ 1
Он назвал двойную фигурную скобку инициализации. (EDIT: ссылка удалена, архивировано здесь)
Это означает, что вы создаете анонимный подкласс, а код в двойных скобках - это в основном конструктор. Он часто используется для добавления содержимого в коллекции, потому что синтаксис Java для создания того, что является по существу коллекционными константами, несколько неудобно.
Итак, вы можете сделать:
List<String> list = new ArrayList<String>() {{
add("one");
add("two");
add("three");
}};
вместо:
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
Мне это действительно не нравится и предпочитаю делать это:
List<String> list = Arrays.asList("one", "two", "three");
Таким образом, в этом случае это не имеет особого смысла, тогда как, например, для карт, у которых нет удобного помощника.
Ответ 2
"Внешние" фигурные скобки означают, что вы создаете анонимный подкласс, а вторая фигурная скобка - инициализатор объекта. Инициализатор запускается перед конструктором класса, но после любых вызовов super
(и, следовательно, также после любых инициализаторов суперкласса). Вы также можете использовать инициализаторы в неанонимных классах, что является удобным способом для запуска полей final
, если у вас есть несколько конструкторов, которые не могут называть друг друга, или поля, которые требуют более сложной инициализации, чем обычные инициализаторы полей.
Рассмотрим этот класс:
class X extends Y{
private final int lulz;
private static boolean someCondition(){...}
private static boolean danger() throws SomeException { ... }
public X(A a) throws SomeException {
super(a);
lulz = someCondition()? danger() : 0;
}
public X(B b) throws SomeException {
super(b);
lulz = someCondition()? danger() : 0;
}
}
Его можно было бы переписать как:
class X extends Y{
private final int lulz;
private static boolean someCondition(){...}
private static boolean danger() throws SomeException { ... }
{ // initalizer -- might throw SomeException!
lulz = someCondition()? danger() : 0;
}
public X(A a) throws SomeException { super(a); }
public X(B b) throws SomeException { super(b); }
}
Если инициализатор может выставить проверенное исключение, все конструкторы должны объявить, что могут его выбросить.
Ответ 3
Вы создаете анонимный класс и используете класс Instance initialize r idiom, например:
class X {
private Y var1;
private X() {
Z context = new Z(
new SystemThreadPool()) {
{ // This is the initialize idiom
var1 = new Y(); //
} //
}
); // BTW you are missing ")"
}
}
Ответ 4
Как упоминалось в предыдущих ответах, правильная инициализация двойной фигурной скобки.
Он использует определенный метод для Инициализации экземпляров в Java. Это сокращенный способ определения в определении класса, общего блока кода, который будет запускаться при активации любого из конструкторов классов.
Я добавляю ссылку на официальную документацию Java описывая ее для более широкого обзора темы.
Из документации:
Блоки инициализатора для переменных экземпляра выглядят как статические инициализаторы, но без статического ключевого слова:
{
// whatever code is needed for initialization goes here
}
Компилятор Java копирует блоки инициализации в каждый конструктор. Поэтому этот подход может использоваться для обмена блоком кода между несколько конструкторов.