Ответ 1
Это (нестатический) блок инициализатора. Это описано в официальном учебнике здесь:
Инициализация членов экземпляра
Обычно вы добавляете код для инициализации переменной экземпляра в конструкторе. Существует две альтернативы использованию конструктора для инициализации переменных экземпляра: блоки инициализации и конечные методы. Блоки инициализатора для переменных экземпляра выглядят так же, как и статические блоки инициализатора, но без статического ключевого слова:
{ // whatever code is needed for initialization goes here }
Компилятор Java копирует блоки инициализации в каждый конструктор. Поэтому этот подход может использоваться для совместного использования блока кода между несколькими конструкторами.
Вот простая демонстрация:
public class Test {
{
System.out.println("Initializer block");
}
Test() {
System.out.println("Constructor 1");
}
Test(int i) {
System.out.println("Constructor 2");
}
public static void main(String[] args) {
new Test();
System.out.println("---");
new Test(1);
}
}
Выход
Initializer block
Constructor 1
---
Initializer block
Constructor 2
Вы можете найти это полезным, если, например, добавить панель JLabel
в панель:
panel.add(new JLabel() {{ setBackground(Color.GREEN); setText("Hello"); }});
Под капотом:
Байт-код блока инициализатора буквально копируется в каждый конструктор. (По крайней мере, Suns javac и компилятор eclipse:
Test();
Code:
0: aload_0
1: invokespecial
4: getstatic #2;
7: ldc #3; //String "Initializer block"
9: invokevirtual #4; //Method PrintStream.println:(String;)V
12: getstatic #2;
15: ldc #5;
17: invokevirtual #4;
20: return
Test(int);
Code:
0: aload_0
1: invokespecial #1;
4: getstatic #2;
7: ldc #3; //String "Initializer block"
9: invokevirtual #4; //Method PrintStream.println:(String;)V
12: getstatic #2;
15: ldc #6;
17: invokevirtual #4;
20: return