为什么这些代码在Java 7而不是Java 8中有效?
我目前正在使用IDE Eclipse版本:Neon.2发行版(4.6.2)和版本java版本8更新131.在此代码中,IDE给出错误 – “类型不匹配:无法从字节转换为整数”:
Integer i = (byte) 10;
但是这个代码在IDE Eclipse Version:Indigo Service Release 2和java Version 7中正确执行。在第8版java中扩展转换机制本质上有所改变,因为我不认为它与IDE版本有关?
这绝对不是JDK的问题,因为在使用javac
编译器的命令行中,代码会在JDK 7和JDK 8中引发相同的编译器错误 –
error: incompatible types Integer i = (byte) 10; ^
事实上,我有Eclipse Mars Release 4.5.0,它给了我与JDK 7和8相同的编译错误。我没有更新的版本所以没有测试那些,但如果它没有抛出编译错误任何使用JDK 7的版本都必须是该JDK版本的eclipse编译器的错误。
只有在一次进行两次转换时,您的作业才有效
- 从
byte
扩展到int
- 从
int
到Integer
拳击
显然,较旧的Eclipse版本允许更改,而javac
从未允许这样做(我测试了Java 6到Java 9)。
为了找出正确的行为,我们参考了规范 :
5.2。 作业上下文
赋值上下文允许将表达式的值赋值(第15.26节)给变量; 必须将表达式的类型转换为变量的类型。
赋值上下文允许使用以下之一:
- 身份转换(第5.1.1节)
- 扩展的原始转换(第5.1.2节)
- 扩大参考转换(第5.1.5节)
- 一个拳击转换(第5.1.7节),可选地后跟一个加宽的引用转换
- 一个拆箱转换(第5.1.8节),可选地后跟一个加宽的基元转换。
请注意,我们需要的代码组合不在列表中。 我们可以从该列表中得出以下内容应该有效:
Number i = (byte) 10;
这是从byte
到Byte
的装箱转换,然后是扩展引用转换为Number
。
要么
Byte b = 42; int i = b;
这是从Byte
到byte
的拆箱转换,然后是从byte
到int
的扩展基元转换。
由于(byte) 10
是编译时常量,我们还必须考虑
此外,如果表达式是
byte
,short
,char
或int
类型的常量表达式(第15.28节):
- 如果变量的类型是
byte
,short
或char
,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。- 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:
Byte
和常量表达式的值可在类型byte
表示。Short
和常量表达式的值可以在short
类型中表示。Character
和常量表达式的值可在char
类型中表示。
来自同一部分。
这允许一些有趣的组合,如
Character c = (byte)10;
要么
Byte b = 'x';
但没有一个变量类型的Integer
如上所述,从byte
到Integer
的转换不在列表中,因此较旧的Eclipse版本允许它的事实可以被认为是在较新版本中已修复的错误。
接受该程序的是ecj中的错误362279 ,该错误已于 2011年修复。
PS:为什么要调查古代版本中的错误? 您只缺少JDT / Core中的1419个错误修复程序。