Consider the following example:
class Quirky {
public static void main(String[] args) {
int x = 1;
int y = 3;
System.out.println(x =
I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable...
There is. Next time you are unclear what the specification says, please read the specification and then ask the question if it is unclear.
... the right side
(x = y)
which, by the order implied by brackets, should be calculated first.
That statement is false. Parentheses do not imply an order of evaluation. In Java, the order of evaluation is left to right, regardless of parentheses. Parentheses determine where the subexpression boundaries are, not the order of evaluation.
Why does the first expression evaluate to false, but the second evaluate to true?
The rule for the ==
operator is: evaluate the left side to produce a value, evaluate the right side to produce a value, compare the values, the comparison is the value of the expression.
In other words, the meaning of expr1 == expr2
is always the same as though you had written temp1 = expr1; temp2 = expr2;
and then evaluated temp1 == temp2
.
The rule for the =
operator with a local variable on the left side is: evaluate the left side to produce a variable, evaluate the right side to produce a value, perform the assignment, the result is the value that was assigned.
So put it together:
x == (x = y)
We have a comparison operator. Evaluate the left side to produce a value -- we get the current value of x
. Evaluate the right side: that's an assignment so we evaluate the left side to produce a variable -- the variable x
-- we evaluate the right side -- the current value of y
-- assign it to x
, and the result is the assigned value. We then compare the original value of x
to the value that was assigned.
You can do (x = y) == x
as an exercise. Again, remember, all the rules for evaluating the left side happen before all the rules of evaluating the right side.
I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.
Your expectation is based on a set of incorrect beliefs about the rules of Java. Hopefully you now have correct beliefs and will in the future expect true things.
This question is different from "order of evaluation of subexpressions in a Java expression"
This statement is false. That question is totally germane.
x is definitely not a 'subexpression' here.
This statement is also false. It is a subexpression twice in each example.
It needs to be loaded for the comparison rather than to be 'evaluated'.
I have no idea what this means.
Apparently you still have many false beliefs. My advice is that you read the specification until your false beliefs are replaced by true beliefs.
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.
The provenance of the expression is not relevant to the question. The rules for such expressions are clearly described in the specification; read it!
It was supposed to be a one-line replacement for the compare-and-replace idiom
Since that one-line replacement caused a great deal of confusion in you, the reader of the code, I would suggest that it was a poor choice. Making the code more concise but harder to understand is not a win. It is unlikely to make the code faster.
Incidentally, C# has compare and replace as a library method, which can be jitted down to a machine instruction. I believe Java does not have such a method, as it cannot be represented in the Java type system.