Kotlin Object Declarations Are Initialized in Static Block
It’s Java static initialization block for Object Declaration of Kotlin in Android, not lazy initializer in the general thought.
In kotlinlang.org, the article said
object declarations are initialized lazily, when accessed for the first time;
a companion object is initialized when the corresponding class is loaded (resolved), matching the semantics of a Java static initializer.
And when I use object declaration in an android project,
object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}val allDataProviders: Collection<DataProvider>
get() = // ...
}
what I expected is DataProviderManager won’t initialize unless I use, as Kotlin official document told.
But what we actually get is (from decompiled by Android Studio)
public final class DataProviderManager {
@Nullable
private static final Collection allDataProviders;
public static final DataProviderManager INSTANCE;
public final void registerDataProvider(@NotNull ContentProvider provider) {
Intrinsics.checkParameterIsNotNull(provider, "provider");
}
@Nullable
public final Collection getAllDataProviders() {
return allDataProviders;
}
static {
DataProviderManager var0 = new DataProviderManager();
INSTANCE = var0;
}
}
we got a static final DataProviderManager INSTANCE
but initialized INSTANCE in a Static Initialization Block. JVM (and Dalvik) guarantees that static initialization blocks are called in the order of the source code when the class is loaded.
Yes, static initialization blocks are kind of lazy initializers. They will execute when static methods are called or there is a reference to the class. But, in most general thinking, lazy initializer looks like
public static Instance getInstance() {
if (instance == null) {
instance = new Instance();
}
}
we don’t hit upon static initialization block.
We might just load the class first but use the instantiated object later, or never. (but I know this case is much rare.)