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

标签 scala generics reflection instanceof type-erasure

为什么 isInstanceOf[T] 方法没有按预期工作?

在下面,我定义了一个 hello 类和伴随对象。在hello对象中,我在代码行“hel.typetest[Int]”中测试了this.isInstanceOf[T],这怎么是true 当类型 TInt?

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))
}

还有特例 support用于在存在 ClassTag 时与 T 进行模式匹配:

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

有人提议让 is/asInstanceOf[T] 在存在 ClassTag 时也能正常工作,但也有一些假设防止这种情况发生并且很难更改的编译器(如果我没记错的话)。

关于scala - 为什么 Scala 方法 isInstanceOf[T] 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59518420/

相关文章:

scala - Akka-HTTP : File Upload

generics - 具有变量类型的 F# 函数

java - 通用类枚举返回类型

linux - 无法从与 jenkins 服务相同的文件中提供 scala/sbt

Scala 类型检查/断言作为函数 vs JVM 类型删除

regex - Scala 按包含所有连字符的行拆分多行字符串

swift - Swift 中的泛型

c# - 如何从枚举中获取数值?

c# - 反射获取 `Parent`对象

Scala 2.10反射: constructor of case class inside a class