Це безпосередньо з http://www.programcreek.com/2011/10/java-class-instan-initializer/
1. Наказ про виконання
Подивіться на наступний клас, чи знаєте ви, хто з них виконується першим?
public class Foo {
//instance variable initializer
String s = "abc";
//constructor
public Foo() {
System.out.println("constructor called");
}
//static initializer
static {
System.out.println("static initializer called");
}
//instance initializer
{
System.out.println("instance initializer called");
}
public static void main(String[] args) {
new Foo();
new Foo();
}
}
Вихід:
статичний ініціалізатор викликається
викликається ініціалізатор екземпляра
конструктор закликав
викликається ініціалізатор екземпляра
конструктор закликав
2. Як працює ініціалізатор екземпляра Java?
Ініціалізатор екземпляра вище містить операцію println. Щоб зрозуміти , як це працює, ми можемо розглядати його як оператор присвоювання змінної, наприклад, b = 0
. Це може зробити його більш зрозумілим для розуміння.
Замість
int b = 0
, можна було написати
int b;
b = 0;
Тому ініціалізатори екземплярів та ініціалізатори змінних екземплярів майже однакові.
3. Коли корисні ініціалізатори екземплярів?
Використання ініціалізаторів екземплярів є рідкісними, але все ж може бути корисною альтернативою екземплярам ініціалізаторів змінних, якщо:
- Код ініціалізатора повинен обробляти винятки
- Виконайте обчислення, які неможливо виразити ініціалізатором змінної екземпляра.
Звичайно, такий код можна було записати в конструкторах. Але якби в класі було кілька конструкторів, вам доведеться повторити код у кожному конструкторі.
За допомогою ініціалізатора екземпляра ви можете просто написати код один раз, і він буде виконуватися незалежно від того, який конструктор використовується для створення об'єкта. (Я думаю, це просто поняття, і воно використовується не часто.)
Інший випадок, коли ініціалізатори екземплярів корисні - це анонімні внутрішні класи, які взагалі не можуть оголосити жодних конструкторів. (Чи це буде вдале місце для розміщення функції реєстрації?)
Завдяки Дерхейну.
Також зауважте, що класи Anonymous, які реалізують інтерфейси [1], не мають конструкторів. Тому ініціалізатори екземплярів потрібні для виконання будь-яких видів виразів під час створення.
public static void staticMethod(){}
, якщо ви виконуєтеTestStatic.class.getMethod("staticMethod");
. Статичний ініціалізатор не буде викликаний. Більше інформації тут docs.oracle.com/javase/specs/jvms/se10/html/…