【问题标题】:Why does this bit of code work in Java 7 and not Java 8?为什么这段代码适用于 Java 7 而不是 Java 8?
【发布时间】:2017-07-14 10:21:51
【问题描述】:

我目前正在使用 IDE Eclipse 版本:Neon.2 Release (4.6.2) 和版本 java Version 8 Update 131。 在这段代码中,IDE 给出了一个错误——“Type mismatch: can not convert from byte to Integer”:

Integer i = (byte) 10;

但是这段代码在IDE Eclipse Version: Indigo Service Release 2和java Version 7中正确执行。java第8版的拉宽转换机制本质上发生了变化,因为我认为它与IDE版本无关?

【问题讨论】:

  • 所以您的问题可以概括为“为什么这段代码在 Java 7 而不是 Java 8 中有效?”。
  • 是的,我不明白,为什么这段代码在 java 7 中运行良好
  • 我在 java 7 和 8 中试过这个都给了我同样的错误。你确定这在 java 7 中有效吗
  • @janith1024 你用过javac吗?我可以确认,这适用于 Eclipse Indigo SR2 (ECJ)。所以,这似乎是 ECJ 中的一个错误。
  • 我在 Intellij idea 中检查了这段代码,使用不同的 JDK(7 和 8)希望 Eclipse 版本中的问题

标签: java eclipse java-8


【解决方案1】:

只有同时进行两次转换,您的分配才会起作用

  1. byte 扩大到int
  2. 拳击从intInteger

显然,较旧的 Eclipse 版本允许这样做,但已更改,而 javac 从未允许这样做(我测试了 Java 6 到 Java 9)。

要找出正确的行为,我们可以参考the specification

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 版本允许它这一事实可以被视为已在新版本中修复的错误。

【讨论】:

  • 显然,你是对的,旧版本的 Eclipse 允许这种转换“字节到整数”,但我没有找到任何关于这个错误(或这个增强)的参考,这个事实很有趣。
  • 并非每个修复都有明确的错误报告,有时,它是重写特定算法的一部分,将修复多个问题。
  • 好吧,我觉得这个话题应该关闭了,因为例如将代码更改为Integer i = Integer.valueOf((byte) 10) 是最好的方法。
  • @Vitaly Vlasov:您的问题是为什么,而不是如何更改代码。如果您想知道如何在代码中解决该问题,那么只需删除过时的 (byte) 演员表 Integer i = 10; 即可。如果你有一个byte 类型的现有变量b,你可以简单地写Integer i = +b;,考虑到一元+ 是一个空操作。但这不是你的问题。所以我不明白,为什么要关闭这个问题。你可以accept 来代替答案……
  • 首先,投票。我认为代码也不能在eclipse中编译。这是一个错误而不是警告。所以我想问 OP,你如何通过javac 在 eclipse 的编译时编译你的代码?也许它根本不会发生。或者可能是 OP 在编写代码期间禁用了 eclipse 验证机制。
【解决方案2】:

接受程序是ecj中的bug 362279,2011年修复。

PS:为什么要费心研究古代版本的错误?您仅在 JDT/Core 中缺少 1419 个错误修复。

【讨论】:

    【解决方案3】:

    这绝对不是 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 编译器的错误。

    【讨论】:

      猜你喜欢
      • 2020-11-13
      • 1970-01-01
      • 2021-03-21
      • 2018-04-24
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 2022-12-20
      • 1970-01-01
      相关资源
      最近更新 更多