At first glance, I was very surprised by the behavior itself, but, on the other hand, itβs quite simple to explain:
private static final SomeClass instance = new SomeClass();
is part of SomeClass static initialization. When you instantiate before initialization is complete, the class is not yet fully initialized. When you replace System.out.println(...); something like new Exception().printStackTrace(); you get this (note that I put all the classes as static nested classes in Main)
at Main$SomeObject.<init>(Main.java:37) // new Exception().printStackTrace(); at Main$SomeClass$1.<init>(Main.java:26) // add(new SomeObject(...)) at Main$SomeClass.<init>(Main.java:23) // list = new ArrayList() at Main$SomeClass.<clinit>(Main.java:10) // instance = new SomeClass() at Main.main(Main.java:6) // SomeClass.getInstance();
As you can see, the execution is still inside Main$SomeClass.<clinit> (class initialization), so SomeClass is not fully initialized.
As a side note: the best way to implement the Singleton pattern is to completely eliminate it. The second most likely option is to use enum (at least approved by Josh Bloch)
class enum SomeClass { instance;
sfussenegger Mar 11 '10 at 8:12 2010-03-11 08:12
source share