当我使用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
有人可以解释最后两个结果吗?
答案 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();
}