0

I had a question in my test that I got confused about (code attached below). To put it shortly, I thought that the variables are reassigned and then added back as a value to the expression (making the output "8, 10") but seems like the original value somehow is not changed. What am I missing?

p.s. Sorry if a similar question exists, I couldn't find one (probably its too obvious :P).

class InitTest{
    public static void main(String[] args){
        int a = 10;
        int b = 20;
        a += (a = 4);
        b = b + (b = 5);
        System.out.println(a + ",  " + b);
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    Please do not write code like this - as you have probably noticed, it is confusing to follow what it actually is doing. –  Sep 02 '20 at 00:10
  • @Taschi: bad code like this is probably the cornerstone of the programming certification exams – Hovercraft Full Of Eels Sep 02 '20 at 00:14
  • @HovercraftFullOfEels, I am not a certified Java dev, but if certification exams actually teach people to rely on edge cases, then it is even more necessary to point out that this is not good code. –  Sep 02 '20 at 00:17
  • 1
    @Taschi-corporationsarebad It's not my code. It was an example and I had to choose an answer. – Artur Shalimov Sep 02 '20 at 00:25

2 Answers2

1
a += (a = 4);

The above is logically equivalent to the following:

a = a + (a = 4);

If we substitute in the existing value for a, then this simplifies to:

a = 10 + 4 = 14

We can do the same for b:

b = b + (b = 5) = 20 + 5 = 25

We see this result because of operator precedence. The addition operator, +, has a higher precedence than the assignment operator, =, as defined by the Java operator precedence table.

You can see that the addition-assignment operator, +=, shares the same precedence with the assignment operator, in which case the expression is evaluated from left to right.


If, instead, the expressions were:

a = (a = 4) + a;
b = (b = 5) + b;

Then it would result in the output that you expect (a = 8, b = 10), as the left operand is computed before the right operand (when evaluating the expression). I'll try to locate where this is specified in the Java Language Specification.

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • 1
    Ooooh, I got it now. My mistake was that I assumed that the value would dynamically change – Artur Shalimov Sep 02 '20 at 00:17
  • 1
    Expressions are evaluated according to operator precedence. It is *operands* that are evaluated left to right. The OP's results are due to operator precedence. – user207421 Sep 02 '20 at 00:24
  • @JacobG.So in this case parentheses are not counted as arithmetic but just as a separator for the assignment? (i thought that parentheses have higher OP) – Artur Shalimov Sep 02 '20 at 00:43
  • @ArturShalimov For more information about the role of parentheses in expression evaluation, I'd look here: [If parenthesis has a higher precedence then why is increment operator solved first?](https://stackoverflow.com/q/28219423/7294647) – Jacob G. Sep 02 '20 at 00:46
-1

In Java when assigning a value to a variable, the first thing that is calculated is the left part of the = sign and then the right. Therefore, when you write a += (a = 4); which is equivalant to a = a + (a=4) which is the same as a = a + 4 , same for b.

  • 1
    Why would the left part of the = sign ever be "calculated"? It's just an identifier. You can't assign something to `a + 5`. –  Sep 02 '20 at 00:15
  • @Taschi-corporationsarebad The left side has to be resolved to a variable, which might be an object's field or an array component; for example, `getObj().getArray()[4] = 5` obviously has to call two methods. The left-hand side is evaluated before the right-hand side is evaluated. – kaya3 Sep 02 '20 at 00:40
  • @kaya3, fair enough, but evaluating is not the same as calculating. My example of `a + 5` is not a valid left side for an assignment. –  Sep 02 '20 at 00:46
  • Whether a computation is or is not a "calculation" is not really defined in a technical sense. But if it has to do arithmetic with numbers to count as a calculation, then `foo(a + 5).bar = "baz";` should meet your criterion. – kaya3 Sep 02 '20 at 11:28