从Odersky的书中写一个简单的例子导致了以下问题:
// AbstractElement.scala
abstract class AbstractElement {
val contents: Array[String]
val height: Int = contents.length // line 3
}
class UnifiedElement(ch: Char, _width: Int, _height: Int) extends AbstractElement { // line 6
val contents = Array.fill(_height)(ch.toString() * _width)
}
object AbstractElement {
def create(ch: Char): AbstractElement = {
new UnifiedElement(ch, 1, 1) // line 12
}
}
Run Code Online (Sandbox Code Playgroud)
,
// ElementApp.scala
import AbstractElement.create
object ElementApp {
def main(args: Array[String]): Unit = {
val e1 = create(' ') // line 6
println(e1.height)
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抛出以下跟踪:
Exception in thread "main" java.lang.NullPointerException
at AbstractElement.<init>(AbstractElement.scala:3)
at UnifiedElement.<init>(AbstractElement.scala:6)
at AbstractElement$.create(AbstractElement.scala:12)
at ElementApp$.main(ElementApp.scala:6)
at ElementApp.main(ElementApp.scala)
Run Code Online (Sandbox Code Playgroud)
所以编译器认为内容仍为null,但我在UnifiedContainer中定义了它!
当我用def和evrth替换val完美时,事情变得更加奇怪!
你能否解释一下这种行为?
mis*_*tor 13
这是Paul P的一篇很棒的文章,它解释了Scala中的初始化顺序错综复杂.根据经验,你绝不应该使用抽象val的.总是使用抽象defs和lazy vals.
| 归档时间: |
|
| 查看次数: |
1784 次 |
| 最近记录: |