Except for 4, all of these rely on operator precedence.
And in Java, +
has precedence over ==
.
Which means 2 actually "reads":
s1 == ((s2 + s1) == s2)
Therefore the right side operand of the first ==
is a boolean expression which compares two object references to one another (the fact that they are both String
s here is irrelevant) and here they are not the same. Hence the right side operand is boolean false
.
But since the left side operand is a String
, and since ==
is not applicable to operands String
and boolean
, this gives a compile error. JLS, section 15.21:
The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.
If this really compiles for you, you are using a buggy Java compiler which autoboxes the right side operand to a Boolean
, which it shouldn't. Let me guess: Eclipse's ECJ?
4 is an error since the +
operator doesn't accept boolean
s as operands.
3 reads nearly the same as 2, except that this time it is s2 + " " + s1
which is (attempted to be) compared to s2
. It fails to compile for the same reason.
In 5, booleans are autoboxed because of string concatenation.
6 again relies on the operator priority mentioned in 2; this time it is string true + " " + s1
which is (reference) compared with s2
(and that gives false). See 5 for what happens to true
.