为什么我可以在从 Java 进行转换时在 Int 中存储 null,但不能在其他情况下存储



在下面的代码中,我正在创建一个Java集合。稍后当我将其转换为 Scala 时,我可以将null存储在 Int 中。但是如果我直接创建 scala 地图,我无法存储null。为什么?

scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> val mapJava:java.util.HashMap[String,java.lang.Integer] =  new java.util.HashMap[String,java.lang.Integer]
mapJava: java.util.HashMap[String,Integer] = {}
scala> mapJava.put("key",null)
res2: Integer = null
scala> println(mapJava)
{key=null}
scala> val mapScala = mapJava.asScala
mapScala: scala.collection.mutable.Map[String,Integer] = Map(key -> null)
scala> val mapScalaI = mapScala.asInstanceOf[scala.collection.Map[String,Int]]
mapScalaI: scala.collection.Map[String,Int] = Map(key -> null) //storing null in Int
//but I cannot store null in Int in following code. why?
scala> val mapScalaI2 = Map[String,Int]("key"->null)
<console>:14: error: an expression of type Null is ineligible for implicit conversion
       val mapScalaI2 = Map[String,Int]("key"->null)
                                               ^
...
scala> val mapScala = mapJava.asScala
mapScala: scala.collection.mutable.Map[String,Integer] = Map(key -> null)
scala> val mapScalaI = mapScala.asInstanceOf[scala.collection.Map[String,Int]]
mapScalaI: scala.collection.Map[String,Int] = Map(key -> null) //storing null in Int
...

从理论上讲,mapScala.asInstanceOf[scala.collection.Map[String,Int]]应该失败,因为 Integer 类型参数与Int类型参数不同。但是,它实际上并没有这样做,因为asInstanceOf由于 Java 类型擦除而没有(或不能(检查Map[String, Int]的类型参数。从scala.Any.asInstanceOf

请注意,运行时强制转换的成功是模 Scala 的擦除语义。因此,表达式 1.asInstanceOf[String] 将在运行时引发ClassCastException,而表达式 List(1).asInstanceOf[List[String]] 不会。在后一个示例中,由于类型参数作为编译的一部分被擦除,因此无法检查列表的内容是否属于请求的类型。

在 Java 中,null可以是任何引用类型的值,例如 java.lang.Integer .

在Scala中,nullNull类型,它是任何引用类型的子类型。 scala.Int是基元类型,而不是引用类型。

类型 Null 的表达式不符合隐式转换的条件

最新更新