Consider the following example:
class Quirky {
public static void main(String[] args) {
int x = 1;
int y = 3;
System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}
I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y
) which, by the order implied by brackets, should be calculated first.
Why does the first expression evaluate to false
, but the second evaluate to true
? I would have expected (x = y)
to be evaluated first, and then it would compare x
with itself (3
) and return true
.
This question is different from order of evaluation of subexpressions in a Java expression in that x
is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y)
, unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom
int oldX = x;
x = y;
return oldX == y;
which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.
==
is a binary equality operator.
The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First