在超类的初始化中使用变量时,覆盖变量会创建一个NPE
假设我们有以下设置:
open class Foo(open val img: Image) { val use = img.graphics } class Bar(override val img: BufferedImage) : Foo(img)
初始化时,使用img.width
创建一个NPE。 我认为问题在于,显然即使img
直接在Bar的构造函数中传递,当它在Foo中使用时,它并不指向它,而是指向Bar类中的重写变量。 我怎样才能避免这一点?
这种行为是由img
的getter被覆盖并返回不同字段的值(因为Bar
用不同的类型覆盖img
,它需要创建一个BufferedImage
类型的附加字段)的事实造成的。 Foo
构造函数在Bar
分配该字段之前执行。
一般来说,你应该避免在你的类的初始化逻辑中使用打开的成员,因为它们可能在子类中被覆盖,并且可能依赖于在超类初始化的时候还没有正确初始化的状态。
对于你的具体情况,在Foo
构造函数中创建一个简单的参数,并明确地使用该参数:
open class Foo(img: Image) { open val img = img val use = img.graphics }