不一致的 null 相等性检查 scala 2.11.7

Inconsistent null equality check scala 2.11.7

编辑:Scala 2.12.6 中不再存在此问题


原始问题(针对 Scala 2.11.7):

为什么这么奇怪的警告?

scala> null.asInstanceOf[Double]
res0: Double = 0.0

scala> null.asInstanceOf[Double] == null
<console>:11: warning: comparing values of types 
      Double and Null using `==' will always yield !!!!false!!!!
       null.asInstanceOf[Double] == null
                                 ^
res1: Boolean = true //!!!!

scala> 0.0 == null
<console>:11: warning: comparing values of types Double and Null using `==' will always yield false
       0.0 == null
           ^
res2: Boolean = false

scala> null.asInstanceOf[Double] == 0.0
res6: Boolean = true

scala> val a = null.asInstanceOf[Double]
a: Double = 0.0

scala> a == null
<console>:12: warning: comparing values of types Double and Null using `==' will always yield false
       a == null
         ^
res7: Boolean = false

P.S。 IntLong

相同

P.S.2 它不是重复的 - 这里的问题是无论 asInstanceOf 怎么装箱都不会发生(正如你从我的回答中看到的那样)+警告信息是不一致

发生这种情况是因为 Java 中的 scala.Double == double 不能包含空值。如果你想要你想要的行为,你可以使用 java.lang.Double 这将能够存储一个空值。

val n = null.asInstanceOf[java.lang.Double]
println("null? = " + n)
//null? = null

另一种防止使用 double 的方法是更明确地说明类型

val n: AnyVal = null.asInstanceOf[Double]
println("null? = " + n)
//null? = null

为了让事情变得更混乱,试试这个:

println("null? = " + null.asInstanceOf[Double])
//null? = null

这表明 double 的使用只会在您的空值分配给 val 时发生。

我对编译器警告没有很好的解释,这个警告在这个特定场景下似乎不正确。

编辑:这个 issue no longer exists in Scala 2.12.6. See pull-request 有解释。


原始答案(针对 Scala 2.11.7):

null.asInstanceOf[Double] == null 编译为:

aconst_null
ifnonnull

val-版本编译为:

aconst_null
invokestatic unboxToDouble
putfield
aload_0
invokevirtual а
invokestatic boxToDouble
ifnonnull

所以编译器只是忘记在第一种情况下添加 unbox/box