为什么isInstanceOf[T]
方法不能按预期工作?
在下面,我定义了一个hello
类和伴随对象。在hello对象中,我在代码“ this.isInstanceOf[T]
”行中测试了hel.typetest[Int]
,当类型true
为T
时,这是Int
吗?
object hello {
def main(args: Array[String]): Unit = {
Console.println("main")
val hel = new hello
hel.typetest[Int]
}
}
class hello {
def typetest[T: ClassTag]: Unit = {
Console.println(this.isInstanceOf[T])
Console.println(this.getClass)
}
}
输出:
main
true
class hello
最佳答案
由于type erasure(连同拳击)。 T
擦除为Object
,因此this.isInstanceOf[T]
在字节码中变为this.isInstanceOf[Object]
,这始终为真。
碰巧的是,ClassTag
旨在避免这种情况,但是您需要实际使用它而不是调用isInstanceOf
:
def typetest[T](implicit tag: ClassTag[T]): Unit = {
Console.println(tag.runtimeClass.isInstance(this))
}
当存在
T
时,还有一种特殊情况的support用于与ClassTag
进行模式匹配:def typetest[T: ClassTag]: Unit = {
Console.println(this match {
case _: T => true
case _ => false
})
}
有一些建议也可以在存在
is
时使asInstanceOf[T]
/ ClassTag
正常工作,但是编译器中内置了一些假设,可以防止这种情况,并且很难更改(如果我正确地记住了原因)。