Zimri Leisher
Zimri Leisher

Reputation: 1376

Overriding variable creates a NPE when variable is used in the initialization in the super class

Say we have the following set up:

open class Foo(open val img: Image) {
    val use = img.graphics
}
class Bar(override val img: BufferedImage) : Foo(img)

On initialization, the use of img.width creates a NPE. What I think the issue is, is that apparently even though img is passed in the constructor of Foo directly in Bar, when it is used in Foo it doesn't point to it, instead it points to the overridden variable in the Bar class. How can I avoid this?

Upvotes: 2

Views: 77

Answers (1)

hotkey
hotkey

Reputation: 147901

This behavior is caused by the fact that the getter of img is overridden and returns the value of a different field (since Bar overrides img with a different type, it requires creating an additional field of type BufferedImage). The Foo constructor is executed before that field is assigned in Bar.

In general, you should avoid using open members in the initialization logic of your classes, because they may be overridden in the subclasses and may rely on some state that, upon the superclass initialization time, is not properly initialized yet.

For your particular case, make img in the Foo constructor a simple parameter and use the parameter explicitly:

open class Foo(img: Image) {
    open val img = img
    val use = img.graphics
}

Upvotes: 2

Related Questions