为什么这些代码在Java 7而不是Java 8中有效?

Vit*_*sov 2 java eclipse java-8

我目前正在使用IDE Eclipse版本:Neon.2发行版(4.6.2)和版本java版本8更新131.在此代码中,IDE发出错误 - "类型不匹配:无法从字节转换为整数":

Integer i = (byte) 10;
Run Code Online (Sandbox Code Playgroud)

但是这个代码在IDE Eclipse Version:Indigo Service Release 2和java Version 7中正确执行.在第8版java的扩展转换机制中有什么实质性的改变,因为我不认为它与IDE版本有关?

Pal*_*nal 7

这绝对不是JDK的问题,因为在使用javac编译器的命令行上,代码会同时使用JDK 7和JDK 8抛出相同的编译器错误 -

error: incompatible types
Integer i = (byte) 10;
            ^
Run Code Online (Sandbox Code Playgroud)

事实上,我有Eclipse Mars Release 4.5.0并且它给了我与JDK 7和8相同的编译错误.我没有更新的版本所以没有测试那些,但如果它没有抛出编译错误任何使用JDK 7的版本都必须是该JDK版本的eclipse编译器的bug.


Hol*_*ger 7

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

  1. 从扩大byte到int
  2. 从拳击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;
Run Code Online (Sandbox Code Playgroud)

这是从... byte到拳击转换Byte,然后是扩展引用转换为Number.

要么

Byte b = 42;
int i = b;
Run Code Online (Sandbox Code Playgroud)

这从解包转换Byte到byte,随后从一个加宽原语转换byte到int.

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

此外,如果表达式类型的常量表达式(§15.28) ,byte,short,char或int:

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

来自同一部分.

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

Character c = (byte)10;
Run Code Online (Sandbox Code Playgroud)

要么

Byte b = 'x';
Run Code Online (Sandbox Code Playgroud)

但没有一个变量类型的 Integer


至于说,从转换byte到Integer不在列表内,让年长的Eclipse版本允许它的事实,可以认为已固定在新版本中的错误.

  • @Vitaly Vlasov:你的问题是*为什么*,而不是如何更改代码.如果你想知道,如何在代码中解决这个问题,那么,只需删除过时的`(byte)`cast,`Integer i = 10;`然后你就完成了.如果你有一个类型为`byte`的现有变量`b`,你可以简单地写`Integer i = + b;`,考虑到一元`+`是一个无操作.但这不是你的问题.所以我不明白,为什么要关闭这个问题.您可以[接受](https://stackoverflow.com/help/accepted-answer)代替答案...... (2认同)

Ste*_*ann 6

接受该计划的是ecj 中的错误362279,该错误已于 2011年修复.

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