允许“布尔”和“对象”的等式比较?
以下代码
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 == two
将Boolean
与Object
进行比较 – 这些都是引用类型,因此测试是引用相等( Java语言规范,Java SE 7版,§15.21.3 ) -
one == three
将Boolean
与boolean
进行比较 – 这被视为原始boolean
值的比较( §15.21.2 );one
是未装箱的,与three
相比较。 -
two == three
比较一个带有boolean
的Object
– 在这种情况下,boolean
通过强制转换转换为Object
( §5.5 ,在本例中为装箱boolean
值为Boolean
,然后加宽Boolean
值为Object
),然后将两者进行比较以供参考平等。
EQUAL
行更简单 – 所有三种情况都是对Boolean.equals(Object other)
调用,当参数为three
时使用装箱。