Składnia inicjalizacji pól instancji to specjalny blok kodu, umieszczony w nawiasach klamrowych wewnątrz klasy, ale poza metodami i konstruktorami. Taki blok nazywa się instance initializer block. Wykonuje się za każdym razem, gdy tworzony jest nowy obiekt klasy, bezpośrednio po wywołaniu konstruktora klasy nadrzędnej i przed wykonaniem kodu konstruktora bieżącej klasy.
public class Example { { // Block inicjalizacji instancji System.out.println("Inicjalizacja instancji"); } private int x; public Example(int x) { this.x = x; System.out.println("Konstruktor"); } }
Instance initializer jest przydatny do:
Co się stanie, jeśli w klasie istnieje zarówno instance initializer, jak i konstruktor? W jakiej kolejności są one wykonywane?
Odpowiedź: Najpierw wykonywany jest instance initializer, a następnie kod konstruktora. Jeśli w klasie jest kilka bloków instance initializer, są one wykonywane w takiej kolejności, w jakiej są opisane.
Przykład:
public class Demo { { System.out.println("Instance initializer 1"); } public Demo() { System.out.println("Konstruktor"); } { System.out.println("Instance initializer 2"); } } // Wynik przy new Demo(): // Instance initializer 1 // Instance initializer 2 // Konstruktor
Historia
Na jednym projekcie programista umieścił logikę w instance initializer zamiast w metodzie lub konstruktorze. Przy dziedziczeniu klasy i nadpisywaniu konstruktora instance initializer i tak został wykonany, co doprowadziło do nieoczekiwanej kolejności inicjalizacji i błędów w logice biznesowej.
Historia
W innym projekcie instance initializer odwoływał się do pól klasy, które zostały zainicjalizowane poniżej w kodzie. Okazało się, że zmienne jeszcze nie były zainicjalizowane, co spowodowało NullPointerException podczas tworzenia obiektu.
Historia
Zespół dodał do instance initializer operację związaną z zewnętrznymi zasobami (BD). W związku z tym każde wywołanie konstruktora tworzyło połączenie z BD, co przeciążyło system przy masowym tworzeniu obiektów.