我有两个看起来像这样的Scala类(释义):
abstract class GenericParser[T] {
val lineFilter : String => Boolean
parseData()
def parseData() : T {
for( line <- .... if lineFilter(line) )
// do things
}
}
class SalesParser extends GenericParser[SalesRow] {
val lineFilter = line => !line.startsWith("//")
// ....
}
问题是lineFilter
中null
为parseData
,大概是因为parseData
在主要GenericParser
构造函数仍在运行时被调用,所以子类尚未完全初始化其成员。
我可以通过将lineFilter设为def
而不是val
来解决这个问题,但这是预期的行为吗?在运行时获得NPE之后,这个问题才会变得明显,这似乎是不对的。
答案 0 :(得分:6)
这确实是预期的行为,与此问题完全相同:
Scala 2.8: how to initialize child class
您基本上可以复制粘贴该问题的答案表单。解决方案包括:
def
或lazy val
代替val
lineFilter
重新设计类以避免“从超类的构造函数中访问未初始化的子类值的虚拟方法调用”问题。例如,为什么要将过滤函数存储在val中或从def返回,而它可以作为方法实现?
abstract class GenericParser[T] {
def lineFilter(line: String): Boolean
parseData()
def parseData() : T {
for( line <- .... if lineFilter(line) )
// do things
}
}
class SalesParser extends GenericParser[SalesRow] {
def lineFilter(line: String) = !line.startsWith("//")
}