Rozumiem, że reguła dla inicjalizatorów statycznych polega na tym, że są one wykonywane tylko raz, po wczytaniu kodu bajtowego klasy i przed wykonaniem dowolnej statycznej metody lub utworzeniu pierwszego obiektu z klasy. JLS gwarantuje, że inicjalizacja zostanie ukończona. Aby zagwarantować, że ta gwarancja jest prawdziwa, JLS określa również, że kod nie mógł zostać nagle zakończony (co wyraźnie podano w innej odpowiedzi).
Należy pamiętać, że możliwe jest ładowanie kodu bajtowego bez jego inicjalizacji; patrz metoda Class.forName(String, boolean, ClassLoader). Jeśli parametr boolean
to false
, to spowoduje załadowanie klasy, ale nie zainicjowanie jej. Programista może jeszcze trochę przemyśleć, aby odkryć informacje o tej klasie bez jej zainicjowania. Jednak po próbie użycia klasy bezpośrednio przez wywołanie metody statycznej lub instancji instancji JVM rozpocznie ją najpierw.
Jeśli jakikolwiek ze statycznych inicjalizatorów nagle przerwie działanie - co może się zdarzyć przy RuntimeException
, klasa pozostanie w niepoprawnym stanie. Po raz pierwszy JVM rzuci ExceptionInInitializeError
(zauważ, że jest to Error
, co oznacza, że jest uznawana za awarię wewnętrzną). Od tego momentu nie będzie możliwe użycie klasy - próba wywołania statycznej metody lub utworzenie instancji obiektu spowoduje, że otrzymasz numer NoClassDefFoundError
.
Jedynym sposobem na odzyskanie tej sytuacji bez restartowania maszyny JVM jest użycie ClassLoader
s oraz zastąpienie programu ładującego klasy błędną klasą i przebudowanie klasy lub reinicjalizatora w innym środowisku (prawdopodobnie w różnych właściwościach systemu), ale program musi być dobrze przygotowany do tego rodzaju sytuacji.
Są to nazywane inicjalizatory statyczne, a nie konstruktory statyczne. Po prostu piszę to, aby pomóc w wyszukiwaniu. – Oak
@Oak: Dzięki (15 znaków) –