Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么int-to-Object比较在Java7中有效,而在Java8中无效?_Java - Fatal编程技术网

为什么int-to-Object比较在Java7中有效,而在Java8中无效?

为什么int-to-Object比较在Java7中有效,而在Java8中无效?,java,Java,以下代码 private boolean compare(Object a, int b) { return a == b; } 在Java 7中编译,但在Java 8中会导致以下错误: 不可比较的类型:int和Object 请看以下问题: 似乎Java6和Java8不允许您比较int和Object,而Java7允许。有关于这方面的文件吗 我对这些决定的背景知识感兴趣。好像他们还没决定什么 我在JDK1.7.0.51中使用14.1.4。Java7将自动装箱应用于int privat

以下代码

private boolean compare(Object a, int b) {
    return a == b;
}
在Java 7中编译,但在Java 8中会导致以下错误:

不可比较的类型:int和Object

请看以下问题:

似乎Java6和Java8不允许您比较
int
Object
,而Java7允许。有关于这方面的文件吗

我对这些决定的背景知识感兴趣。好像他们还没决定什么


我在JDK1.7.0.51中使用14.1.4。

Java7将自动装箱应用于int

 private boolean compare(java.lang.Object, int);
   Code:
      0: aload_1
      1: iload_2
      2: invokestatic  #2       // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      5: if_acmpne     12
      8: iconst_1
      9: goto          13
     12: iconst_0
     13: ireturn
我用
build 1.7.0_71-b14

编辑:

Oracle将此行为视为错误:
:Javac接受错误的二进制比较操作

相关JLS部分为15.21。Javac似乎将此视为 引用比较,但仅当 两个操作数都是引用类型。

JLS第15.21节中二进制比较的类型规则现在将 由javac正确执行。自从JDK5以来,javac已经接受了一些 具有类型错误的对象基元比较的程序 根据JLS 15.21。现在将正确地进行这些比较 标识为类型错误


我无法获得编译的示例(修复bool)→ boolean)使用javac1.7.0_75,也不使用javac1.8.0_60。我没有JDK6,但我认为它也不应该在那里工作。正如Axel所暗示的,这可能是早期ecj的不兼容,也可能是javac的另一个次要版本中的错误

在任何情况下,如果它工作,这是由于自动装箱。这可能是在为Java 8做准备时缩减的,因为流和自动装箱混合得不太好。

提到了3种不同的
==
运算符:数值运算符、布尔运算符和引用运算符在您的示例中,
==
运算符中没有一个,因此我们断定语句是非法的

让我们看看为什么在您的示例中不能应用
==

  • 不需要说明为什么它不相关

  • 如果相等运算符的操作数都是引用类型或null类型,则该操作为对象相等

    如果无法通过强制转换()将任一操作数的类型转换为另一个操作数的类型,则这是编译时错误。两个操作数的运行时值必然不相等。

  • 如果相等运算符的操作数都是数字类型,或者一个是数字类型,另一个可转换为数字类型(),则对操作数()执行二进制数字升级

现在让我们假设它是合法的,编译器将行更改为:

if (a == new Integer(b))

你期望结果是什么?该条件的计算结果永远不会为
true
,因此有理由认为这是一个在Java8中修复的bug

根据
int
可与装箱数字类型进行比较,即字节、短字符、字符、整数、长字符、浮点、双精度。但仅此而已


如果比较是在
int
之间,并且说是
Float
,那么
Float
将首先解除绑定,这样比较是在
Float
int
之间进行的。用另一种方法绕过-box
int
,然后检查
整数的标识(使用
浮点数
)是没有意义的。

错误是在eclipse中显示的(即使用ecj时)还是由JDK编译器显示的?我猜这是ecj中的一个错误……如果是这样的话,我会认为Java 7与Oracle的Java 7犯了一个错误,我得到了“不兼容的操作数类型:Object和int”。您是否提供了您在Java 7编译中观察到的确切代码?@andythonas我想这取决于1.7 jdk的具体版本。llogiq不能用JDK1.7.0_75编译,而wero可以用JDK1.7.0_71编译。也许他们在这些版本之间修复了一个bug?jdk 1.7.0上的编译失败,但是自动装箱是使用
Integer.valueOf
完成的。由于
Integer.valueOf
有时会从池中返回值,因此结果可能是
true
@fabian所以,以合理有用或直观的方式永远不会为true。@Marounnaroun好吧,对于答案中的代码,它肯定永远不会为true
newinteger(b)
总是创建一个对象,而
Integer.valueOf(b)
可能不会。正如其他评论者所说,这个答案是错误的。使用自动装箱可以很好地定义比较整数和对象。