Что делает {{ ... }}
блок в следующем коде?Значение нового класса (...) {{...}} Инициализация idiom
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
Что делает {{ ... }}
блок в следующем коде?Значение нового класса (...) {{...}} Инициализация idiom
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
Это называется double curly brace initialization. (EDIT: ссылка удалена, archived here)
Это означает, что вы создаете анонимный подкласс, а код в двойных фигурных скобках - это в основном конструктор. Он часто используется для добавления содержимого в коллекции, потому что синтаксис 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");
Так что Безразлично» В этом случае имеет смысл, тогда как, например, Карты, у которых нет удобного помощника.
@skaffman Это очень полезно в «жидкой java», такой как [JATL] (http://code.google.com/p/jatl) попытки. –
Обратите внимание, что Arrays.asList() возвращает java.util.Arrays.ArrayList.ArrayList, а не java.util.ArrayList, который имеет ограниченную функциональность. – Asaf
Эта техника сложна и имеет некоторые оговорки. В конечном итоге можно сломать контракт equals() или увеличить использование памяти без уважительной причины. Лучше избегать инициализации двойной привязки, если вы точно не знаете, что делаете. Посмотрите на [this] (http://www.ayp-sd.blogspot.com/2012/12/double-brace-initialization-in-java.html) сообщение для более подробной информации. –
«Внешние» фигурные скобки означают, что вы создаете анонимный подкласс, а вторая фигурная скобка - инициализатор объекта. Инициализатор запускается перед конструктором класса, но после любых вызовов 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); }
}
Если инициализатор может бросить проверяемое исключение, все конструкторы должны объявить они могут бросить его.
Вы создаете anonymous class и используя class Instance initialize г идиомы, например:
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 ")"
}
}
Как уже упоминалось в предыдущих ответах, двойной инициализации фигурная скобка правильно.
Он использует конкретную технику для Инициализация членов экземпляра в Java. Это сокращенный способ определения в определении класса, общего блока кода, который будет запускаться при активации любого из конструкторов классов.
Я добавляю ссылку на official Java documentations, описывая ее для более широкого обзора по теме.
От documentation:
Initializer блоки для переменных экземпляра выглядят так же, как статические инициализатора блоков, но без статического ключевого слова:
{
// whatever code is needed for initialization goes here
}
Компилятор Java копирует блоки инициализации int o каждый конструктор. Следовательно, этот подход может использоваться для совместного использования блока кода между несколькими конструкторами.
Я думаю, что это непросто для Google для двойных фигурных скобок. –
@Tom Hawtin: вы можете использовать Google для «двойной скобки» ... –