A question regarding constructors: consider the fo...
# announcements
t
A question regarding constructors: consider the following class hierarchy
Copy code
class 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
?
a
https://kotlinlang.org/docs/reference/classes.html#derived-class-initialization-order says
During 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
It means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized.
t
I see. Then why didn't IntelliJ warn me that I might call a non-final method in the initializer 😕
m
If you make your class
Base
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"