根据scala docs:
Null是所有引用类型的子类型;
所以从理论上讲,在这个例子中,我们可以假设Null
是Foo
(参考类型)的子类型,我们应该可以尝试调用bar
方法类型为Null
的实例。在实践中,我们不能和代码片段在编译时失败,错误为value bar is not a member of Null
。
case class Foo(bar: String)
val n: Null = null
n.bar
我认为我们在编译时捕获它是有道理的,因为scala文档也是say [Null's] only instance is the null reference
,但我认为更好的错误消息是Calling bar on type Null can only result in a NullPointerException
。
我的问题是关于以下代码片段,它在编译时没有失败,而是在运行时因NullPointerException
而失败
val n: Null = null
n.toString
我假设这是因为Null类型并不真正子类化其他所有引用类型而只是子类AnyRef
,但是有任何理由不应该抛出编译时错误(或者至少警告)此代码只能导致NullPointerException
?是故意调用null.bar
和null.toString
的行为有何不同?
答案 0 :(得分:0)
Null is a subtype of all reference types;
- 这意味着类似的东西:
val n: Foo = null
n.bar //throws NPE
val a: String = null
a.charAt(0) //NPE again
所以你可以说Null
是所有引用类型的子类型。
编辑
val n: Null = null
n.bar
部分不正确。根据Scala文档:
abstract final class Null extends AnyRef
AnyRef
没有bar
。你不能这样说,对吧?
val n: AnyRef = ""
n.charAt(0) //won't compile