为什么 Scala 方法 isInstanceOf[T] 不起作用

Tyl*_*归玉门 3 generics reflection scala instanceof type-erasure

为什么该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)
  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

main
true
class hello
Run Code Online (Sandbox Code Playgroud)

Ale*_*nov 8

因为类型擦除(连同拳击)。T擦除到Object,因此this.isInstanceOf[T]变成this.isInstanceOf[Object]字节码,这总是正确的。

碰巧,ClassTag旨在避免这种情况,但您需要实际使用它而不是调用isInstanceOf

def typetest[T](implicit tag: ClassTag[T]): Unit = {
  Console.println(tag.runtimeClass.isInstance(this))
}
Run Code Online (Sandbox Code Playgroud)

当 a存在时,还有对模式匹配的特殊情况支持TClassTag

def typetest[T: ClassTag]: Unit = {
  Console.println(this match {
    case _: T => true
    case _ => false
  })
}
Run Code Online (Sandbox Code Playgroud)

也有人建议在 a存在时使is/asInstanceOf[T]正常工作ClassTag,但是编译器中内置了一些假设来防止这种情况发生并且很难改变(如果我没记错原因的话)。