tschuchort
08/14/2018, 4:36 PMclass Base(private val x: X) {
val a: Int = throw IllegalStateException(
"something went wrong with $this") // calls Derived::toString
}
class Derived(private val x: X) : Base(x) {
override fun toString() = x.toString() //NullPtrException: x is null
}
val d = Derived(X())
How can it be that there is a NullPtrException in Derived::toString
when it's called by Base::<init>
initializing Base::a
? is Derived::x
not set before giving it to the constructor of Base
?Andreas Sinz
08/14/2018, 4:58 PMDuring construction of a new instance of a derived class, the base class initialization is done as the first step (preceded only by evaluation of the arguments for the base class constructor) and thus happens before the initialization logic of the derived class is run.
, so Derived.x
is initialized AFTER Base
Andreas Sinz
08/14/2018, 4:58 PMIt means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized.
tschuchort
08/14/2018, 5:11 PMmglukhikh
08/15/2018, 9:20 AMBase
open
(otherwise your code just do not compile), you will get a weak warning on `$this`: "Leaking 'this' in constructor of non-final class Base"