This code throws a NullPointerException but is accepted by the compiler:
data class Foo(val value: String)
abstract class A {
abstract var foo: Foo
init {
println(foo.value)
}
}
class B : A() {
override var foo: Foo = Foo("Hello, World!")
}
fun main(args: Array<String>) {
var b = B()
println(b.foo.value)
}
As foo is not nullable I expect it not to be null when the constructor is called.
But A’s constructor is called before B’s and thus foo has is not initialized when A’s constructor is called.
And the null safety is broken.
The code may not necessarily be broken it depends on the subclass implementation. If you declared a custom getter in the subclass that just returned a constant the code would have ran fine. So there is no reason to exclude it at compile time, but it is a known gotcha that applies to Java and Kotlin equally.
The same situation occurs in Java and it generates no warning. In many cases such access is perfectly valid and not an issue. I see no point in making people deal with warnings that may not be valid.
It’s not implemented for Kotlin yet, but for Java there is an inspection in IntelliJ IDEA warning when virtual methods are called within the constructor. I think it is only a matter of time until this would be implemented for Kotlin.