为什么1.asInstanceOf [T]不会抛出ClassCastException?

时间:2015-10-15 16:12:13

标签: scala

scala> def g[T] = 1.asInstanceOf[T]
g: [T]=> T

scala> g[String]
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  ... 32 elided

scala> { g[String]; 1 }
res0: Int = 1

可是:

scala> def f = 1.asInstanceOf[String]
f: String

scala> { f; 1 }
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  at .f(<console>:7)
  ... 32 elided

这里的逻辑是什么?如何在类型参数函数中触发ClassCastException

1 个答案:

答案 0 :(得分:1)

此警告回答了我的问题:

scala> def g[T] = 1.isInstanceOf[T]
<console>:7: warning: abstract type T is unchecked since it is eliminated by erasure
       def g[T] = 1.isInstanceOf[T]
                                ^

所以asInstanceOf[T]是一个编译时强制转换。它在运行时没有任何影响。在我得到ClassCastException的情况下,它不是由asInstanceOf[T]引发的,而是由在函数外部发生的实际转换引起的。

解决方案是使用ClassTag并使用classTag[T].runtimeClass.cast。但行为略有不同:您可以在asInstanceOf[Double]上使用Int,但cast会因ClassCastException而失败。这个问题的解决方案是使用Apache commons-lang的{​​{3}}。