3

当我使用 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

谁能解释最后两个结果?

4

2 回答 2

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 提供的泛型机制的一般特性/限制。有关详细信息,请参阅类型擦除

于 2012-06-14T21:21:51.040 回答
5

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

请注意,这些也将产生 true:

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();
}
于 2012-06-14T21:33:59.507 回答