Are object declarations (singletons) initialized s...
# language-evolution
a
Are object declarations (singletons) initialized statically or at the first access? The docs says:
Object declaration's initialization is thread-safe and done at first access.
But the following code
Copy code
object TestObject {
    val a = "hello"
    fun b(): Nothing = TODO()
}
decompiles as follows:
Copy code
public final class TestObject {
   @NotNull
   private static final String a;
   public static final TestObject INSTANCE;

   @NotNull
   public final String getA() {
      return a;
   }

   @NotNull
   public final Void b() {
      boolean var1 = false;
      throw (Throwable)(new NotImplementedError((String)null, 1, (DefaultConstructorMarker)null));
   }

   private TestObject() {
   }

   static {
      TestObject var0 = new TestObject();
      INSTANCE = var0;
      a = "hello";
   }
}
Tested with/without property and with/without function declaration. Same behavior static initialization, is the docs outdated?
z
On the JVM, static fields are initialized when the class is first loaded, which is (at least in most cases) the first time the class (or any of its members) is accessed.
You can see this, for example, if you have a
compileOnly
dependency on some library and then run some code that tries using some API from that library – an exception will be thrown the first time you try accessing the API.
a
I mean, first access means referencing the object right?
(in runtime)
(in a similar way lazy delegate works, i.e. I was considering docs implies initialization at getter maybe of field INSTANCE here)
z
Objects are initialized when the object’s class is initialized, which happens the first time the object is accessed. Property initialized run at this time as well. There no difference between “static” and “first access” here
n
It is worth noting that this behaviour is up to the JVM implementation (afaik) https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4 not sure I linked the right paragraph, but my remark is that you should not make your logic depend on when objects are initialised. If you need this kind of 'lazy' behaviour (initialise when referenced) use
lazy
. This will also make it explicit and readable