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:
- 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") - figure out the parameters (i.e. evaluate
x = y
, which will changex
to point to the String "goodbye" and also return a reference to that String) - 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 writeif(b)
since(b == true)
will always give same result as already stored inb
. - In case of
if(b==false)
we can writeif(!b)
.
- In case of
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 withtrue = b
which will end up as compilation error since we can't assign anything to value liketrue
(just like we can't compile2=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.
- 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";
- 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".
- 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
Drawing an Object Using Getgraphics() Without Extending Jframe
Eclipse Windowbuilder, Overlapping JPAnels
How to Print Line Numbers to the Log in Java
Is There an Equivalent of Java.Util.Regex for "Glob" Type Patterns
Why Does Arraylist Have "Implements List"
Rotating Image with Affinetransform
Technique or Utility to Minimize Java "Warm-Up" Time
Should I Close the Servlet Outputstream
<Form Action="/Sampleservlet" Giving Me Exception
Graphics Rendering in Title Bar
Timer & Timertask Versus Thread + Sleep in Java
Should I Call Ugi.Checktgtandreloginfromkeytab() Before Every Action on Hadoop
Run .Exe File in Java from File Location
How to Set Icon to a Jlabel from an Image from a Folder
System.Currenttimemillis() VS. New Date() VS. Calendar.Getinstance().Gettime()