In this code, `foo` is null in the init of the `Pa...
# getting-started
j
In this code,
foo
is null in the init of the
Parent
class.
test
fails to initialize due to NullPointerException. Why? How do I get around this? In my actual code,
foo
is actually being overridden to be a particular subclass. But in this example, I'm just using String. Overriding is necessary here.
Copy code
fun main() {
    val test = Child()
}

open class Parent(
    open val foo: String = "Hello",
) {
    init {
        println(foo.length)
    }
}

class Child(
	override val foo: String = "World",
) : Parent(foo)
s
This is down to the order in which things are initialized when you have several classes in a hierarchy. Constructors and property initializers in the superclass run before constructors and initializers in the subclass. So the
init
block in your
Parent
class runs before
Child.foo
has been assigned a value. Even though
foo
is non-nullable, it will still temporarily appear to be null if accessed before initialization.
You should get a warning in the IDE about this, it'll say something like "accessing non-final property in constructor"
e
you may want to write
Copy code
open class Parent(
    val foo: String = "Hello",
) {
    init {
        println(foo.length)
    }
}

class Child(
    foo: String = "World",
) : Parent(foo)
which does not have any use before initialization
j
Thanks @Sam. For some reason, I thought that the subclasses' primary constructor was the first thing to run.. not sure why. Unfortunately I needed these classes to be serializable, so the constructors can't have parameters which aren't properties
e
then I would not use a concrete base class.
Copy code
interface Base {
    val foo: String
}
class One(override val foo: String = "Hello") : Base
class Two(override val foo: String = "World") : Base
open val
+
override val
is usually a bad idea. you end up with an inaccessible backing field in the base class which is shadowed