为什么isInstanceOf[T]方法不能按预期工作?

在下面,我定义了一个hello类和伴随对象。在hello对象中,我在代码“ this.isInstanceOf[T]”行中测试了hel.typetest[Int],当类型trueT时,这是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正常工作,但是编译器中内置了一些假设,可以防止这种情况,并且很难更改(如果我正确地记住了原因)。

10-07 18:05