// This code compiles, but leads to an NPE on a non-nullable type
class Foo {
val output = doSomething()
val input = "This value is not set yet"
fun doSomething(): String = input.uppercase()
}
The order of the class properties matters, as
input
is still
null
, when
doSomething()
is called. This is trivial to see in this example, but tricky in more complex scenarios. Is this expected behavior? Couldn't the compiler notice the nullability issue?
d
dmitriy.novozhilov
05/09/2023, 11:52 AM
It is a known problem (KTIJ-9751)
Generally there is no solution for it in the compiler, which will work for definite amount of time, because it requires cross-functional analysis (which may lead to situation that you need to look through all the sources to understand that some call in the constructor is safe). There are some heuristics in the IDE plugin, but they don't cover all possible cases
dmitriy.novozhilov
05/09/2023, 11:53 AM
There is a simple rule which helps to avoid such bugs: never leak
this
in class initialization (contstuctors, property initializers, init blocks), even to members of the same class
s
sciack
05/09/2023, 12:34 PM
Happen to me extending some Swing Component in Intellij plugin, the "Abstract" constructor was calling properties that was not initialised yet, I had to make the properties nullable even if was logically never null.
h
Hannes Korte
05/09/2023, 12:45 PM
Interesting, and thanks for the issue link. Also the rule to "never leak
this
in class initialization" is good to know.
p
peekandpoke
05/10/2023, 8:38 AM
Another workaround might be to make those properties lazy that depend on the class being initialized: