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
?
答案 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}}。