以下代码,
private boolean compare(Object a, int b) {
return a == b;
}
Run Code Online (Sandbox Code Playgroud)
在Java 7中编译,但它导致Java 8中出现以下错误:
无与伦比的类型:int和Object
看看以下问题:
这似乎像Java 6和Java 8,不要让你比较int和Object,而7一样.有没有这方面的文件?
我对通知这些决定的背景知识很感兴趣.看起来他们还没有决定.
我正在使用IntelliJ IDEA 14.1.4和JDK 1.7.0.51.
wer*_*ero 30
Java 7将自动装箱应用于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
Run Code Online (Sandbox Code Playgroud)
我创造了这个 build 1.7.0_71-b14
编辑:
Oracle认识到此行为并将其视为错误:
JDK-8013357:Javac接受错误的二进制比较操作
相关的JLS部分是15.21.Javac似乎将此视为参考比较,但仅当BOTH操作数是引用类型时才允许引用比较.
...
JLS第15.21节中的二进制比较的类型规则现在将由javac正确实施.从JDK5开始,javac接受了一些程序,这些程序的对象原语比较根据JLS 15.21输入错误.现在,这些比较将被正确识别为类型错误.
Mar*_*oun 22
所述JLS -第15章相等运算提到3个不同的==操作符:数值,布尔和参考.无的的==运营商可以在你的例子发生,所以我们得出结论,声明是非法的.
让我们看看为什么==不能在你的例子中应用:
不用说为什么它不相关..
如果等于运算符的操作数既是引用类型又是null类型,则操作是对象相等.
如果无法通过转换转换将任一操作数的类型转换为另一个操作数的类型,那么这是一个编译时错误(第5.5节).两个操作数的运行时值必然是不相等的.
如果等于运算符的操作数都是数字类型,或者一个是数字类型而另一个是可转换的(第5.1.8节)为数字类型,则对操作数执行二进制数字提升(第5.6.2节).
现在让我们假设它是合法的,并且编译器将该行更改为:
if (a == new Integer(b))
Run Code Online (Sandbox Code Playgroud)
您对结果的期望是什么?这个条件永远不会评估true,因此它是一个在Java 8中修复的错误.
我无法用javac 1.7.0_75编译(修复bool→boolean),也不能用javac 1.8.0_60编译.我没有JDK6,但我认为它也不应该在那里工作.也许它是早期的ecj不兼容性,正如Axel提示的那样,或者是javac的另一个次要版本中的错误.
无论如何,如果它有效,那是由于自动装箱.为了准备Java 8,这可能已经被削减了,因为流和自动装箱不能很好地混合.