【发布时间】:2011-07-20 03:14:57
【问题描述】:
我一直在阅读 Java 语言规范,第 3 版,并发现我认为规范和 javac 编译器实现之间存在差异。 Eclipse 编译器中也存在相同的差异。
15.16 部分讨论强制转换表达式。它说如果参数类型无法通过强制转换转换为强制类型转换(第 5.5 节),则应该是编译时错误:
如果操作数的编译时类型可能永远不会根据强制转换规则(第 5.5 节)强制转换为强制转换运算符指定的类型,则这是编译时错误。否则,在运行时,操作数的值会通过强制转换为强制转换运算符指定的类型进行转换(如有必要)。
5.5 部分讨论了转换转换。它给出了允许的转换类型列表。列表中特别缺少的是“拆箱转换,然后是扩大/缩小原始转换”。 但是 javac 编译器(以及 Eclipse 编译器)似乎确实允许这种确切的转换顺序。例如:
long l = (long) Integer.valueOf(45);
... 编译得很好。 (有问题的转换是转换为long;参数是java.lang.Integer 类型,因此转换需要取消装箱到int,然后是扩大的原始转换)。
同样,根据 JLS,它应该不可能从 byte 转换为 char,因为(根据 5.1.4)需要扩大基元转换和缩小基元转换 - 但是,编译器也允许这种转换。
谁能赐教?
编辑: 自从提出这个问题后,我已经向 Oracle 提交了 bug report。他们的回答是,这是“JLS 中的一个小故障”。
【问题讨论】:
-
一个更好的例子是
long l = (long) Integer.valueOf(45); -
感谢您的建议,我已经编辑了问题。