Java 将对象和原语与'==';操作人员
以下(Java)代码合法吗Java 将对象和原语与'==';操作人员,java,operators,autoboxing,jls,Java,Operators,Autoboxing,Jls,以下(Java)代码合法吗 class Test { Object foo() {return "";} boolean bar() {return foo() == true;} } 它不会针对JDK 6编译,但在7+上似乎可以。规格改变了吗?一个bug被修复了吗?我已经在上讨论过了,在这个问题上我可以选择任何一种方式。这是字节码供参考 class Test { Test(); Code: 0: aload_0 1: invokespecial
class Test {
Object foo() {return "";}
boolean bar() {return foo() == true;}
}
它不会针对JDK 6编译,但在7+上似乎可以。规格改变了吗?一个bug被修复了吗?我已经在上讨论过了,在这个问题上我可以选择任何一种方式。这是字节码供参考
class Test {
Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
4: return
java.lang.Object foo();
Code:
0: ldc #2 // String
2: areturn
boolean bar();
Code:
0: aload_0
1: invokevirtual #3 // Method foo:()Ljava/lang/Object;
4: iconst_1
5: invokestatic #4 // Method java/lang/Boolean.valueOf:
8: if_acmpne 15
11: iconst_1
12: goto 16
15: iconst_0
16: ireturn
}
它似乎正在将返回的
字符串
转换为一个未装箱的布尔值。JLS关于引用相等性在java 6和java 7之间没有变化:
:
如果相等运算符的操作数都是引用
类型或空类型,则操作为对象相等
如果无法转换类型,则为编译时错误
通过强制转换将一个操作数转换为另一个操作数的类型
(§5.5). 两个操作数的运行时值必须是
不平等
然而,我注意到一些变化。将布尔值强制转换为对象似乎被归类为Java 7上的装箱约定:
基元类型的表达式可以进行强制转换为
通过装箱转换,引用类型无错误
⊡ 表示拳击转换
因此,由于原语true
可以强制转换为对象
,因此您的等式表达式可以在Java 7上归类为引用等式,并且不会产生编译器错误,因为事实证明,将原语与编译时类型为“Object”的表达式进行比较是不合法的。明确禁止:
相等运算符可用于比较两个相同的操作数
可转换()为数值类型,或两个布尔类型的操作数
或布尔值,或两个操作数,每个操作数都是引用类型或
空类型。所有其他情况都会导致编译时错误
Eclipse编译器会标记错误,而不管Java版本如何。对于Java7,OracleJDK和OpenJDK都错误地允许编译代码。Oracle和Open JDK中的这一点在版本8中得到了纠正
总之,根据规范,这种不可靠的比较是非法的,并且只会在编译器的某些子集上编译语言版本目标的特定子集。不会在Java4或8+上工作。其他答案中提到的强制转换仅适用于“=”运算符,而不适用于“==”。仅适用于两个引用操作数。检查上一篇文章,
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)