What Does an Assignment Expression Evaluate to in Java

What does an assignment expression evaluate to in Java?

The assignment operator in Java evaluates to the assigned value (like it does in, e.g., c). So here, readLine() will be executed, and its return value stored in line. That stored value is then checked against null, and if it's null then the loop will terminate.

confused with return value of assignment operation in java

You've got it right. The operator precedence rules make sure that first the == operator is evaluated. That's b1==false, yielding true. After that, the assigned is executed, setting b2 to true. Finally, the assignment operator returns the value as b2, which is evaluated by the if statement.

Java assignment operator execution

First of all: that's an interesting question, but should never come up in "real code", as assigning to the variable you call in the very same line is confusing even if you know how it works.

What happens here is these 3 steps:

  1. figure out which object to call the method on (i.e. evaluate the first x, this will result in a reference to the String "hello")
  2. figure out the parameters (i.e. evaluate x = y, which will change x to point to the String "goodbye" and also return a reference to that String)
  3. call the method equals on the result of #1 using the result of #2 as the parameter (which will be references to the Strings "hello" and "goodbye" respectively).

Looking at the byte code produced for that method makes it clear (assuming you're fluent in Java bytecode):

     0: ldc           #2                  // String hello
2: astore_1
3: ldc #3 // String goodbye
5: astore_2
6: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: dup
12: astore_1
13: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
16: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
19: return

Line #9 is step 1 above (i.e. evaluates x and remembers the value).

Line #10-12 is step 2. It loads y, duplicates it (once for assigning, once for the return value of the assignment expression) and assigns it to x.

Line #13 invokes equals on the result computed in Line #9 and the result of Lines #10-12.

Why does this if statement, with an assignment and equality check, evaluate to false?

The expression is not parsed the way you think. It's not

(test1=false) || (test1 == false)

in which case the result would have been true, but

test1 = (false || test1 == false)

The value of false || test1 == false expression is computed first, and it is false, because test1 is set to true going into the computation.

The reason it is parsed this way is that the precedence of the || is lower than that of the == operator, but higher than the precedence of the assignment operator =.

Its correct answer is 22. But I am getting 24. Where am I wrong? I evaluate the assignment operator += in last as it has the lowest precedence

The += operator, like all compound operators, evaluates the variable on the left first, before evaluating all other operands, and before any operations are actually performed. This is specified by the JLS, Section 15.26.2:

If the left-hand operand expression is not an array access expression, then:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

(bold emphasis mine)

That means that a is evaluated (and saved) to 5 on the left side before the a++ and ++a are evaluated on the right side. The right side does evaluate to 17, but because the left side is still 5, the sum is 22, not 24.

How is if/while condition evaluated when we use assignments instead of comparison?

  • = is assignment operator,
  • == is comparison operator.

But assignment operator

x = y

not only assigns value from y to variable x, but it also returns that value.

Thanks to that we can write code like

x = y = z = 1;
//equivalent of:
x = (y = (z = 1));

(although it is not recommended as it can be confusing, especially for new Java programmers)

As you see 1 is first assigned to variable z, then expression z = 1 returns 1 which can be assigned to variable y. Then again assigning 1 to y returns 1 which can be assigned to variable x.

Because of that returning mechanism it is possible to write code like if (b = true) since true will be assigned to b and then returned. Since if(..) expected boolean for its condition, and found one code compiled fine.

In other words if(b=true){...} is very similar to if(true){b=true; ...}. This means that such if will always execute code from true branch (since that is what we ware assigning to b).



BONUS: How to prevent this typo?

  • omit ==true and ==false parts.

    • In case of if(b==true) we can write if(b) since (b == true) will always give same result as already stored in b.
    • In case of if(b==false) we can write if(!b).
  • use Yoda conditions if(true == b){..} where value is used before/on left side and variable on right side of ==.

    Even if by mistake we will write = instead of == we will end up with true = b which will end up as compilation error since we can't assign anything to value like true (just like we can't compile 2=3; which would attempt to assign 3 to 2 which makes no sense). We can only assign values to variables.

How is expression in method parameter is interpreted?

Your code is equivalent to

node = this.getChildOf(node);
this.moveNode(node);

You should refactor it in two separate instructions as I did above, because it makes the code more readable and obvious.
It's also easier to debug, because you can more easily choose to put the breakpoint wherever you want.

What's the point of evaluating left operand of assignment operator in C?

When x is evaluated as an lvalue, it does not evaluate to 10. It evaluates to an lvalue where the value of the RHS can be stored. If the LHS does not evaluate to an lvalue, the statement would be an error.

From the C99 Standard (6.3.2.1/1):

An lvalue is an expression (with an object type other than void) that potentially designates an object; if an lvalue does not designate an object when it is evaluated, the behavior is undefined.

The evaluation of the LHS as an lvalue is trivial when you have a simple variable, such as

 x = 10;

However, it can be more complex.

 double array[10];
int getIndex(); // Some function that can return an index based
// on other data and logic.

array[getIndex()+1] = 10.0;

// This looks like a function call that returns a value.
// But, it still evaluates to a "storage area".
int *getIndex2() { return(&array[0]); }
*getIndex2()=123.45; // array[0]=123.45

If getIndex() returns 5, then the LHS evaluates to an lvalue that designates the 7-th element of the array.

What is the result of an assignment expression in C?

c = 10 is an expression returning 10 which also assigns 10 to c.

Differences between Java order of expression, operator precedence and associativity

You are correct, they misspoke, assignment operator has the lowest order of precedence.

You are incorrect, they never mention "order of evaluation" anywhere (that you've shown, anyway). The code shown doesn't do anything where order of evaluation matters. The assignment has nothing to with order of evaluation.





  1. The code does not compile because the assignment operator has the highest order of precedence in this expression.

Operator precedence shows:

9   >   relational
2 ?: ternary
1 = assignment

Which means that to explicitly show precedence using parenthesis, the statement becomes:

statement = ((250 > 338) ? lion : tiger) = " is Bigger";



  1. Both sides of the ternary operator must have the same type. This expression is invalid, as the left side of the second assignment operator is not a variable, so the answer is option F.

The ternary operator being ((250 > 338) ? lion : tiger), "both sides" refer to the two assignment operators.

As it says, "This expression is invalid, as the left side of the second assignment operator is not a variable".




  1. Note that if the question had added explicit parentheses around the expression (Tiger = " is Bigger"), option E would have the correct output.

You already confirmed that yourself.

To explicitly show precedence using parenthesis, the statement becomes:

statement = ( (250 > 338) ? lion : (tiger = " is Bigger") );


Related Topics



Leave a reply



Submit