请考虑以下事项:
trait Foo { def bar: Any }
现在,3
和X
甚至没有方法bar
,但这会编译:
val a = 3.asInstanceOf[Int with Foo]
object X
val b = X.asInstanceOf[X.type with Foo]
此代码在编译和运行时(在Scala 2.10.3上)不会产生错误。但是,以下将干净地编译,但会在运行时生成ClassCastException
:
val a1 = a.asInstanceOf[Foo]
val b1 = b.asInstanceOf[Foo]
这怎么可能?我几乎可以接受这样一个事实,即没有对显式演员表进行静态分析/检查,并且他们不鼓励并且通常不需要 - 尽管我确实认为Scala 可以发出关于肯定不正确的警告类型转换,因为object X
没有办法可以拥有特征Foo
,也没有整数 - 但是我不能轻易接受这样一个事实:整数可以在运行时转换为交集包含完全不相关的和非空特征的类型。
答案 0 :(得分:2)
问题是JVM不支持交集类型,因此没有明显的运行时等效于asInstanceOf[Int with Foo]
。这与asInstanceOf[T]
基本上是同一个问题,其中T
是一个通用参数(在Scala和等效的Java中):你也有一个看似在运行时成功的强制转换但实际上在后面的代码中插入强制转换它使用T
的方法。
一种可能性是将转换编译为Int with Foo
作为两个强制转换为Int
和Foo
,但这通常不起作用(例如,当没有运行时)转换为Foo
本身,或者将值传递给采用Int with Foo
的方法。