JLS是否足够好?
强制转换将应用于强制转换操作符的操作数(第15.16节):操作数表达式的类型必须转换为强制转换操作符显式命名的类型。铸造上下文允许使用:
- 身份转换(第5.1.1节)
- 不断扩大的原始转换(第5.1.2节)
- 缩小的原始转换(第5.1.3节)
- 扩展参考转换(第5.1.5节)(可选),然后是未经检查的转换(第5.1.9节)
- 变窄的引用转换(第5.1.6节),然后可以选择进行未经检查的转换
- 拳击转换(第5.1.7节)
- 拆箱转换(第5.1.8节)。
实际上,也许这部分更相关:
将编译时参考类型 S 的值转换为编译时参考类型 T的 转换时编译时合法性的详细规则如下:
如果 S 是类类型:
- 如果 T 是类类型,则| S | <:| T |或| T | <:| S |;
否则会发生编译时错误。此外,如果存在的超类型 X 的 Ť ,和超类型 ÿ 的 小号 ,使得两个 X 和 ÿ
是可证明不同参数化类型(§4.5),并且的擦除 X 和 ÿ 是相同的,编译时发生错误。- 如果 T 是接口类型:
- 如果 小号 不是
final类(§8.1.1),然后,如果存在的超类型 X 的 Ť ,和超类型 ÿ 的 小号
,使得两个 X 和 ÿ 是可证明不同参数化类型,那的擦除 X 和 Y 相同,则发生编译时错误。否则,强制转换在编译时始终合法(因为即使
S 不实现 T , S 的子类也可能实现)。如果 S 是一个
final类(第8.1.1节),则 S 必须实现 T ,否则会发生编译时错误。如果 T 是类型变量,则使用 T 的上限代替 T 递归地应用此算法。
- 如果 T 是数组类型,则 S 必须是class
Object,否则会发生编译时错误。- 如果 S 是接口类型:
- 如果 T 是数组类型,则 T 必须实现 S ,否则会发生编译时错误。
- 如果 Ť 是一个类型不
final(§8.1.1),然后,如果存在的超类型 X 的 Ť ,和超类型 ÿ 的 小号
,使得两个 X 和 ÿ 是可证明不同参数化类型,那的擦除 X 和 Y 相同,则发生编译时错误。否则,强制转换在编译时始终合法(因为即使
T 不实现 S , T 的子类也可能实现)。- 如果 T 是的类型
final,则:- 如果 S 不是参数化类型或原始类型,则 T 必须实现 S ,并且在静态上知道强制转换正确,否则会发生编译时错误。
- 否则, S 是调用某些通用类型声明 G 的参数化类型,或者是对应于通用类型声明 G 的原始类型。然后必须存在一个超类型
X 的 Ť ,使得 X 是的调用 ģ ,或发生编译时间错误。此外,如果 S 和 X
是可证明是不同的参数化类型,则将发生编译时错误。- 如果 S 是类型变量,则使用 S 的上限代替 S 递归地应用此算法。
- 如果 S 是数组类型 SC [],即,数组类型为 SC 的组件:
- 如果 T 是一个类类型,则如果 T 不是 一个类类型,
Object则会发生编译时错误(因为这Object是可以分配数组的唯一类类型)。- 如果 T 是接口类型,则除非 T 是类型
java.io.Serializable或typeCloneable,否则会发生编译时错误 ,这是由数组实现的唯一接口。- 如果 T 是类型变量,则:
- 如果 T 的上限是
Object或typejava.io.Serializable或typeCloneable,或者可以通过递归应用这些规则将 S 合法地强制转换为类型变量,则该强制转换是合法的(尽管未选中)。- 如果 T 的上限是数组类型 TC [] ,则发生编译时错误,除非可以通过递归应用这些编译时规则来将类型 SC []
强制转换为 TC [] 。- 否则,将发生编译时错误。
- 如果 T 是一个数组类型 TC [],即一个类型为 TC 的组件的数组,那么除非满足以下条件之一,否则发生编译时错误:
- TC 和 SC 是相同的原始类型。
- TC 和 SC 是引用类型,可以通过递归应用这些编译时规则来将类型 SC 强制转换为 TC 。
现在完全清楚了,不是吗?:D
换句话说,这是我不知道有关您的问题的更多详细信息所能做的最好的事情。



