The following code
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
}
}
compiles without errors with javac
V1.7.0_15, and prints "false" when run. However, Eclipse Juno complains about "Incompatible operand types Object and boolean".
Apparently javac autoboxes the primitive boolean b
, and then compares o
and autoboxed b
by object equality, yielding false
, while Eclipse refuses to do the autoboxing.
Which is the right behaviour according to the Java Language Specification? Where should I file a bug?
Note: If I change the type of o
to Boolean
, things work as expected: Eclipse accepts the code, and the code prints "true".
Runnable version on ideone.com
It's your project language level setting. You are probably using a Java 7 compiler with Java 6 semantics. I don't have Eclipse here, but I reproduced it in IntelliJ, which gave errors when the language level was on Java 6, even though the compiler I used was 7. I guess Eclipse has the same. This link explains it.
Concerning your 'Note' that the code compiles and works when o
is changed to Boolean
:
This code:
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)));
}
}
produces this result:
SAME 1:2 false 1:3 true 2:3 false
EQUAL 1:2 true 1:3 true 2:3 true
To see why this is, we need to consider the compile-time types of the various expressions:
one == two
compares a Boolean
with an Object
- these are both reference types, so the test is reference equality (Java Language Specification, Java SE 7 edition, §15.21.3)one == three
compares a Boolean
with a boolean
- this is treated as a comparison of primitive boolean
values (§15.21.2); one
is unboxed and compared with three
.two == three
compares an Object
with a boolean
- in this case the boolean
is converted to Object
by a casting conversion (§5.5, in this case boxing boolean
to Boolean
and then widening Boolean
to Object
) and the two are then compared for reference equality.The EQUAL
line is much simpler - all three cases are calls to Boolean.equals(Object other)
, using boxing when the argument is three
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With