为什么这些代码在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编译器的错误。

只有在一次进行两次转换时,您的作业才有效

  1. byte扩展到int
  2. intInteger拳击

显然,较旧的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; 

这是从byteByte的装箱转换,然后是扩展引用转换为Number

要么

 Byte b = 42; int i = b; 

这是从Bytebyte的拆箱转换,然后是从byteint的扩展基元转换。

由于(byte) 10是编译时常量,我们还必须考虑

此外,如果表达式是byteshortcharint类型的常量表达式(第15.28节):

  • 如果变量的类型是byteshortchar ,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。
  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:
    • Byte和常量表达式的值可在类型byte表示。
    • Short和常量表达式的值可以在short类型中表示。
    • Character和常量表达式的值可在char类型中表示。

来自同一部分。

这允许一些有趣的组合,如

 Character c = (byte)10; 

要么

 Byte b = 'x'; 

但没有一个变量类型的Integer


如上所述,从byteInteger的转换不在列表中,因此较旧的Eclipse版本允许它的事实可以被认为是在较新版本中已修复的错误。

接受该程序的是ecj中的错误362279 ,该错误已于 2011年修复。

PS:为什么要调查古代版本中的错误? 您只缺少JDT / Core中的1419个错误修复程序。