2016-02-23 2 views
3

Почему так странно предупреждение?Несогласованность проверки нулевого равенства 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. То же самое для Int и Long

PS2 Это не дубликат - проблема здесь заключается в том, что бокс не происходит вообще, независимо от asInstanceOf (как вы можете видеть из моего ответа) + предупреждающее сообщение не соответствует

+3

HTTP://stackoverflow.com/questions/10749010/if-an-int-cant-be-null-what-does-null-asinstanceofint-mean –

+0

Хотя я не могу найти ничего в спецификации, которая явно согласуется с ответ. –

ответ

1

null.asInstanceOf[Double] == null компилирует к:

aconst_null 
ifnonnull 

val -версия компилирует в:

aconst_null 
invokestatic unboxToDouble 
putfield 
aload_0 
invokevirtual а 
invokestatic boxToDouble 
ifnonnull 

Так компилятор просто забывает добавить распаковывать/коробка в первом случае

-2

Это происходит потому, что scala.Double == double в Java, который не может содержать нулевое значение. Если вы хотите получить желаемое поведение, вы можете использовать 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.

У меня нет хорошего объяснения для предупреждения компилятора, это предупреждение не кажется правильным, это конкретный сценарий.

Смежные вопросы