Recent days, I wrote and decompiled a Kotlin object, such as one below:
object Test {}
And it turns out to be something like this:
public final class Test {
public static final Test INSTANCE;
private Test() {
INSTANCE = (Test)this;
}
static {
new Test();
}
}
It seems that it is similar to the Eager Implementation of Java Singleton.
The singleton instance will initialized when the class is loaded, not the class is used.
So, is there any reason why the Kotlin use the Eager Implementation not the Static-Holder Implementation which being widely used, or the Enum Implementation which described at Effective Java 2nd Edition as the Best Practice of Singleton?
The singleton instance will initialized when the class is loaded, not the class is used
Isn’t the class loaded when it’s first used. I know several events when JVM loads a class, they include instantiation via construction, access to static fields and invocation of static methods. In case of Kotlin object, we get class loaded (and therefore object instantiated) at the point where someone gets INSTANCE field from Java, or just takes instance of object in Kotlin.
The JVM specification states clearly when the class gets initialized. Other JVM implementations can’t implement different behaviour, since, unlike C++, there no such thing like “undefined behaviour” in Java and JVM.
Not every usage of reflection causes class initialization. AFAIK, only Class.forName does, and only if you pass specific value for a specific parameter. Classpath scanners not necessarily use reflection, actually they are trying to detect jars and folders which constitute classpath and scan these folders and jars for .class files, since Java does not provide API to enumerate all classes.