以下代码
public class TestComparison {
public static void main(String[] args) throws Exception {
boolean b = true;
Object o = new Boolean(true);
System.out.println("comparison result: "+
(o == b)); // Eclipse complains about this expression
}
}
使用javac
V1.7.0_15编译时没有错误,并在运行时打印“false”。但是,Eclipse Juno抱怨“不兼容的操作数类型Object和boolean”。
显然,javac自动装箱原始布尔b
,然后通过对象相等比较o
和自动装箱b
,产生false
,而Eclipse拒绝进行自动装箱。 / p>
根据Java语言规范,哪种行为是正确的?我应该在哪里提交错误?
注意:如果我将o
的类型更改为Boolean
,则按预期工作:Eclipse接受代码,代码打印为“true”。
答案 0 :(得分:7)
这是您的项目语言级别设置。您可能正在使用具有Java 6语义的Java 7编译器。我在这里没有Eclipse,但是我在IntelliJ中重现了它,当Java 6上的语言级别出现错误时,即使我使用的编译器是7.我猜Eclipse也是一样的。 This link解释了它。
答案 1 :(得分:3)
关于“注意”,代码在o
更改为Boolean
时编译并运行:
此代码:
public class Tester{
public static void main(String args[]){
Boolean one = new Boolean(true);
Object two = new Boolean(true);
boolean three = true;
System.out.println("SAME 1:2 " + (one == two) + " 1:3 " + (one == three) + " 2:3 " + (two == three));
System.out.println("EQUAL 1:2 " + (one.equals(two)) + " 1:3 " + (one.equals(three)) + " 2:3 " + (two.equals(three)));
}
}
产生这个结果:
SAME 1:2 false 1:3 true 2:3 false
EQUAL 1:2 true 1:3 true 2:3 true
要了解其原因,我们需要考虑各种表达式的编译时类型:
one == two
将Boolean
与Object
进行比较 - 这些都是引用类型,因此测试是引用相等(Java Language Specification, Java SE 7 edition, §15.21.3)one == three
将Boolean
与boolean
进行比较 - 这被视为原始boolean
值(§15.21.2)的比较; one
已取消装箱,并与three
进行比较。two == three
将Object
与boolean
进行比较 - 在这种情况下,boolean
通过强制转换转换为Object
§5.5 ,在这种情况下,将boolean
装箱到Boolean
,然后将Boolean
加宽到Object
),然后比较两者的参考相等性。 EQUAL
行更简单 - 所有三种情况都是Boolean.equals(Object other)
的调用,当参数为three
时使用装箱。