Statyczny inicjalizator w Javie to blok kodu umieszczony w klamrach i poprzedzony słowem kluczowym static. Taki blok jest wykonywany raz podczas ładowania klasy do JVM, przed utworzeniem jakichkolwiek instancji tej klasy i przed wywołaniem jakichkolwiek metod statycznych. Jego głównym zadaniem jest wykonywanie złożonej inicjalizacji zmiennych statycznych.
public class Example { static int staticValue; static { staticValue = 10; // Złożona logika inicjalizacji System.out.println("Statyczny blok inicjalizacji wykonany"); } }
Statyczny inicjalizator jest szczególnie przydatny, gdy zmienna statyczna zależy od innych zasobów lub wymaga przetwarzania podczas ładowania klasy.
Pytanie: "W jakiej kolejności są wykonywane bloki statyczne i inicjalizacja zmiennych statycznych w Javie, jeśli kolejność ich deklaracji jest różna w klasie?"
Poprawna odpowiedź: Wszystkie zmienne statyczne i bloki są inicjalizowane w kolejności, w jakiej są zadeklarowane w kodzie źródłowym klasy (od góry do dołu). Jeśli zmienna statyczna jest używana w bloku statycznym umieszczonym powyżej jej definicji, spowoduje to błąd kompilacji lub może prowadzić do nieoczekiwanej wartości.
class Order { static { System.out.println(X); // wartość domyślna: 0 } static int X = 100; static { System.out.println(X); // 100 } }
Historia
W dużym projekcie zainicjowano logger za pomocą statycznego bloku, jednak w wyniku zamiany miejscami deklaracji zmiennych i statycznych bloków, zmienna loggera pozostała niezainicjowana w momencie wywołania, co doprowadziło do NullPointerException podczas logowania w czasie ładowania klasy.
Historia
Przy tworzeniu narzędzia JDBC inicjalizacja sterowników odbywała się w statycznym bloku. Jeden z programistów przeniósł deklarację zmiennej String, która zawierała ścieżkę, poniżej statycznego bloku, a kod przestał poprawnie łączyć się z bazą danych — ścieżka była null.
Historia
W rozproszonej systemie pojawiły się problemy z ładowaniem danych konfiguracyjnych: część logiki była realizowana za pomocą statycznych bloków w kilku klasach z wzajemnymi odniesieniami, co prowadziło do cyklicznych inicjalizacji i StackOverflowError podczas uruchamiania aplikacji, z powodu niewłaściwej organizacji statycznych bloków i zależności.