为什么构造函数中的重写 val 为 null?
Why is the overriden val in constructor null?
在以下场景中
class A(name:String, job:String)
{
def profile = name + " " + job
}
class B(name:String, job:String)
{
val a = new A(name,job)
val b = a.profile
}
关于初始化 B
和覆盖 val a
val b = new B("Sasha","Day dream")
{ override val a = new A("John-Wick","Kill") }
我得到 NullPointerException
val b = a.profile
。我的问题是为什么覆盖 val
null ?做上面那样的事情是一种不好的做法吗?
这是几个事实的组合:
a
在val b = a.profile
中指的是getter方法,就是getter(还有setter,对于var
) 被 override val a
覆盖。所以它returns来自子类的字段的值。
子类字段在子类构造函数中初始化
B
构造函数在子类构造函数之前运行,而子类字段有其默认值null
.
一个常见的修复方法是将 val
切换为 lazy val
,以便在首次使用时对其进行初始化。
在以下场景中
class A(name:String, job:String)
{
def profile = name + " " + job
}
class B(name:String, job:String)
{
val a = new A(name,job)
val b = a.profile
}
关于初始化 B
和覆盖 val a
val b = new B("Sasha","Day dream")
{ override val a = new A("John-Wick","Kill") }
我得到 NullPointerException
val b = a.profile
。我的问题是为什么覆盖 val
null ?做上面那样的事情是一种不好的做法吗?
这是几个事实的组合:
a
在val b = a.profile
中指的是getter方法,就是getter(还有setter,对于var
) 被override val a
覆盖。所以它returns来自子类的字段的值。子类字段在子类构造函数中初始化
B
构造函数在子类构造函数之前运行,而子类字段有其默认值null
.
一个常见的修复方法是将 val
切换为 lazy val
,以便在首次使用时对其进行初始化。