本文介绍了抽象超类 scala 中的断言创建 NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
以下代码,在 REPL 中输入时
The following code, when entered in REPL
abstract class A { val aSet: Set[Int]; require(aSet.contains(3)) }
class B extends A { val aSet = Set(4,5,6) }
new B()
给出一个空点异常,而不是一个不变的失败.
gives a null point exception, rather than an invariant failure.
解决这个问题的最佳习语是什么?
What would be the best idiom to solve this problem?
类似问题:
以及在线评论:https://gist.github.com/jkpl/4932e8730c19d81010>
and also online commentary: https://gist.github.com/jkpl/4932e8730c1810261381851b13dfd29d
推荐答案
When you declare a val
, several things happen:
abstract class A { val aSet: Set[Int]; require(aSet.contains(3)) }
class B extends A { val aSet = Set(4,5,6) }
new B()
abstract class A {
private var aSet_A: Set[Int] = null
def aSet: Set[Int] = aSet_A
require(aSet.contains(3))
}
class B extends A {
private var aSet_B: Set[Int] = Set(4,5,6)
override def aSet: Set[Int] = aSet_B
}
new B()
aSet_A
和aSet_B
的内存被分配并设置为null
.A
的初始化程序已运行.require
onaSet.contains(3)
被调用- 由于
aSet
在B
中被覆盖,它返回aSet_B
. - 由于
aSet_B
为null
,因此抛出 NPE.
- Memory for
aSet_A
andaSet_B
is allocated and set tonull
. - Initializer of
A
is run. require
onaSet.contains(3)
is invoked- Since
aSet
is overridden inB
, it returnsaSet_B
. - Since
aSet_B
isnull
, an NPE is thrown.
To avoid this, you can implement aSet
as a lazy variable:
abstract class A {
def aSet: Set[Int]
require(aSet.contains(3))
}
class B extends A {
lazy val aSet = Set(4,5,6)
}
new B()
java.lang.IllegalArgumentException: requirement failed
Obligatory link to Scala's FAQ:
相关问题列表:
这篇关于抽象超类 scala 中的断言创建 NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!