允许“布尔”和“对象”的等式比较?

以下代码

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抱怨“不兼容的操作数类型对象和布尔值”。

显然javac自动装箱原始布尔b ,然后通过对象相等比较o和autoboxed b ,产生false ,而Eclipse拒绝进行自动装箱。

根据Java语言规范,哪种是正确的行为? 我应该在哪里提交错误?

注意:如果我将o的类型更改为Boolean ,则按预期工作:Eclipse接受代码,代码打印为“true”。

ideone.com上的Runnable版本

这是您的项目语言级别设置。 您可能正在使用具有Java 6语义的Java 7编译器。 我在这里没有Eclipse,但是我在IntelliJ中重现了它,当Java 6上的语言级别出现错误时,即使我使用的编译器是7.我猜Eclipse也是一样的。 这个链接解释了它。

关于你的’注意’,代码编译并在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 == twoBooleanObject进行比较 – 这些都是引用类型,因此测试是引用相等( Java语言规范,Java SE 7版,§15.21.3 )
  • one == threeBooleanboolean进行比较 – 这被视为原始boolean值的比较( §15.21.2 ); one是未装箱的,与three相比较。
  • two == three比较一个带有booleanObject – 在这种情况下, boolean通过强制转换转换为Object ( §5.5 ,在本例中为装箱boolean值为Boolean ,然后加宽Boolean值为Object ),然后将两者进行比较以供参考平等。

EQUAL行更简单 – 所有三种情况都是对Boolean.equals(Object other)调用,当参数为three时使用装箱。