Jibidus
07/23/2025, 4:27 PMobject Parent {
val instance = MyObject(Child.childValue)
val parentValue = "other"
object Child {
val childValue = parentValue
}
}
data class MyObject(
val value: String,
)
fun main() {
println(Parent.Child.childValue)
}
Is it an expected behavior? Shouldn't the compilation fail instead?
Here is the stacktrace:
Exception in thread "main" java.lang.ExceptionInInitializerError
at Parent$Child.<clinit>(Main.kt:6)
at MainKt.main(Main.kt:15)
at MainKt.main(Main.kt)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method MyObject.<init>, parameter value
at MyObject.<init>(Main.kt)
at Parent.<clinit>(Main.kt:2)
PHondogo
07/23/2025, 4:41 PMphldavies
07/23/2025, 4:45 PMParent
on instantiation triggers the Child
to be instantiated (via the usage of Child.childValue
) - at the point of Child.childValue
being instantiated, the static value for the parent instance hasn't been instantiated and the value of parentValue
is still null - resulting in that null being stored on the childValue
and subsequently passed to MyObject
constructor.Child
the JVM will attempt to instantiate it, at which point it's <init>
method will reference Parent.parentValue
which triggers instantiation of Parent
. Parent.<init>
references an already-instantiating Child
field which has yet to be populated (as the JVM is still instantiating Parent
from which it will acquire the value to populate on childValue
) and as such it's still null
when being passed to MyObject
)phldavies
07/23/2025, 4:47 PMval instance = MyObject(Child.childValue)
or make it lazy val instance by lazy { MyObject(Child.childValue) }
it should workRob Elliot
07/23/2025, 5:00 PMJibidus
07/23/2025, 5:37 PM