Dies ist von effektivem Java:
%Vor%Beachten Sie, dass die Operationskonstanten in die stringToEnum-Map eingefügt werden aus einem statischen Block, der nach der Erstellung der Konstanten ausgeführt wird. Der Versuch, jede Konstante konstant zu machen, setzt sich selbst in die Karte ein Konstruktor würde einen Kompilierungsfehler verursachen. Das ist eine gute Sache, weil es eine NullPointerException verursachen würde, wenn es legal wäre. Enum Konstruktoren dürfen nicht auf die statischen Felder der Enumeration zugreifen, außer für Konstantenfelder zur Kompilierungszeit. Diese Einschränkung ist notwendig weil diese statischen Felder noch nicht initialisiert wurden, als die Konstruktoren ausführen.
Meine Frage bezieht sich auf die Zeile:
"Beachten Sie, dass die Operationskonstanten in die stringToEnum-Map eingefügt werden von einem statischen Block, der ausgeführt wird, nachdem die Konstanten erstellt wurden. "
Ich dachte, der statische Block wird ausgeführt, bevor der Konstruktor ausgeführt wird. Die werden tatsächlich während der Ladezeit der Klasse ausgeführt.
Was fehlt mir hier?
Ich verstehe Ihre Frage als: Warum gibt es eine Garantie, dass die Enum-Konstanten initialisiert werden, bevor der statische Block ausgeführt wird. Die Antwort finden Sie in der JLS , und a Ein konkretes Beispiel finden Sie in # 8.9.2.1 folgende Erklärung:
Die statische Initialisierung erfolgt von oben nach unten.
und die enums-Konstanten sind implizit endgültig statisch und werden vor dem statischen Initialisierungsblock deklariert.
BEARBEITEN
Das Verhalten unterscheidet sich nicht von einer normalen Klasse. Der folgende Code wird gedruckt:
%Vor% %Vor% Operation
Konstanten sind statische Felder, die im statischen Block in der erscheinenden Reihenfolge erstellt werden.
Die Blöcke static
werden in der Reihenfolge ihrer Erscheinung ausgeführt (Sie können mehrere statische Blöcke haben), wenn der Klassenlader die Klasse lädt, z. Es läuft vor dem Konstruktor.