为什么List [Int]是List [Boolean]的实例?

时间:2012-06-14 21:15:42

标签: scala

当我使用Scala REPL(Scala 2.9.1)时,我看到了isInstanceOf方法的一个令人惊讶的结果:

scala> val l = List[Int](1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> l.isInstanceOf[List[Int]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res3: Boolean = true

scala> l.isInstanceOf[List[String]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res4: Boolean = true

scala> l.isInstanceOf[List[Boolean]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res5: Boolean = true

有人可以解释最后两个结果吗?

2 个答案:

答案 0 :(得分:11)

使用-unchecked重新运行:

scala> l.isInstanceOf[List[Int]]
<console>:9: warning: non variable type-argument Int in type List[Int] is 
unchecked since it is eliminated by erasure
              l.isInstanceOf[List[Int]]
                        ^

在运行时只知道对象的特定类型。这是JVM提供的泛型机制的一般特征/限制。有关详细信息,请参阅Type erasure

答案 1 :(得分:5)

这是由于类型擦除,它将List中的Int类型参数替换为它可以找到的最通用类型绑定。在这种情况下,我相信这是scala.Any。

注意这些也会产生真实:

scala> l.isInstanceOf[List[scala.Nothing]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res0: Boolean = true

scala> l.isInstanceOf[List[Any]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res1: Boolean = true

scala> l.isInstanceOf[List[Object]]
warning: there were 1 unchecked warnings; re-run with -unchecked for details
res2: Boolean = true

使用javap来反汇编这个简单的类,我们可以看到List [Int]中实际上没有泛型类型:

class Bar{
  val list = List[Int](1,2,3)
}

反汇编的scala代码:

public class Bar extends java.lang.Object implements scala.ScalaObject{
  public scala.collection.immutable.List list();
  public Bar();
}