一段程序从java迁移到scala后遇到的,
private val map = new java.util.concurrent.ConcurrentHashMap[String, Int]
val c = map.get(key)
// 下面的if语句在eclipse里提示
// comparing values of types Int and Null using `==' will always yield false
if (c == null) {
...
}
问题简化后如下:
scala> val m = new java.util.concurrent.ConcurrentHashMap[String, Int]
m: java.util.concurrent.ConcurrentHashMap[String,Int] = {}
scala> m.get("key")
res0: Int = 0
scala> val m = new java.util.concurrent.ConcurrentHashMap[String, java.lang.Integer]
m: java.util.concurrent.ConcurrentHashMap[String,Integer] = {}
scala> m.get("key")
res2: Integer = null
为何value设置为scala里的Int
类型得到0而用java里的Integer
确是null? 跟以前遇到的null造型为值类型时为何不抛异常 是相似的事
$ scala -Xprint:jvm -e 'val m = new java.util.concurrent.ConcurrentHashMap[String, Int]; val c = m.get("key")'
...
anon$1.this.m = new java.util.concurrent.ConcurrentHashMap();
anon$1.this.c = scala.Int.unbox(anon$1.this.m().get("key"));
...
$ scala -Xprint:jvm -e 'val n:Int = null.asInstanceOf[Int]' ...
anon$1.this.n = scala.Int.unbox(null);
...
scala> val n:Int = null.asInstanceOf[Int]
n: Int = 0
scala> scala.Int.unbox(null)
res3: Int = 0
scala> null.asInstanceOf[java.lang.Integer]
res5: Integer = null
scala> null.asInstanceOf[Int]
res6: Int = 0
在 scala.Int.unbox
注释里提到运行时是 scala.runtime.BoxesRunTime
里的unboxToInt
方法
package scala.runtime.BoxesRunTime;
public static int unboxToInt(Object i) {
return i == null ? 0 : ((java.lang.Integer)i).intValue();
}
还是在对待Int类型时,两种语言设计上的差异,Scala里统一了primitive类型和引用类型。