Lets take a look at the comments:
// static inner class - inner classes are not loaded until they are referenced.
The "loading" is the process of initialising the inner class (LoggerHolder).
"until they are referenced" means the inner class (LoggerHolder) is not initialised until the LoggerHolder.logger static field is referenced ("used somewhere") in this case.
So the call to getInstance() references LoggerHolder.logger and starts the initialisation of the LoggerHolder inner class.
The whole process of initialising a class is synchronised by the JVM.
From the relevant documentation:
Because the Java programming language is multithreaded, initialization
of a class or interface requires careful synchronization
The implementation of
the Java Virtual Machine is responsible for taking care of
synchronization and recursive initialization
The initialisation of the static field:
private static Logger logger = new Logger();
is a part of the inner class initialisation and this whole initialisation process ("loading") is effectively synchronised by the JVM.
static
keyword is special in Java, and implies a happens-before edge due to the way Java classes are loaded and initialized.) – Hampsteadfinal
andstatic
do. It's one or the other, it doesn't need to befinal
. Didn't double check but I'm sure that's in Brian Goetz's book. Please check it again! – Hampstead