The position of nested classes does not make sense. You can reference a nested class before (earlier in the source text) that it is declared, just as you can reference methods before they are declared.
This is because a nested class is actually an independent class. The closing class and nested class are initialized independently.
So, let's say that neither Bar nor Baz are initialized.
If some code needs Bar , then Bar will be initialized. Baz will not initialize at this time, since Bar not related to Baz .
If any code needs Baz (none of them have yet been initialized), Baz initialization begins. When the Baz constructor for A starts to work, Bar is still not initialized. The first line requires Bar , and the initialization of Bar begins. Bar initialization completes normally, completely, before the first.add(description) statement is first.add(description) . The second statement can also be executed because Bar fully initialized.
As you can see, there is no conflict of initialization conflicts. Bar will be fully initialized and therefore fully accessible for use by the Baz constructor.
To see the sequence of events, I added several print statements:
public class Test { public static void main(String[] args) { Bar.Baz x = Bar.Baz.A; } } class Bar { static { System.out.println("Bar initializing..."); } static List<String> first = new ArrayList<>(); enum Baz { A("Some string"), B("Some other string"), ; static { System.out.println("Baz initializing..."); } Baz(String description) { System.out.println(getClass() + "." + name() + " in construction...");
Exit
class Bar$Baz.A in construction... Bar initializing... Bar initialized class Bar$Baz.A constructed... class Bar$Baz.B in construction... class Bar$Baz.B constructed... Baz initializing... Baz initialized...
As you can see, Bar will start initializing after being used inside the Baz constructor, and at that time it will be fully initialized. Therefore, it is fully available for use by Baz , regardless of the source code.
You can also see that Baz static initializers do not start until enums are created, which, of course, does not allow you to refer to static members from the constructor.