Question

The following 3 lines of code below compile OK. (Please note that this code is an example of "artificial Java coding", and consequently wouldn't be seen in professionally written code.)

int x, y;
boolean b=true;

x = b ? y=1 : 2;  // Compiles OK.

If I now change the code in line #3 above, so that it looks like the following code line below, the compiler generates an error.

// Change the position of the "y assignment", and now the code doesn't compile.
x = b ? 1 : y=2;  

Here is the syntax error message:

Ternary operator syntax error

Can someone please explain this behaviour (to a rookie Java learner)? Thank you.

Was it helpful?

Solution

Short:

This is because of operator precedence. The first case is equal to this:

x = (b ? (y=1) : 2);  // Compiles OK.

While the second is:

x = (b ? 1 : y) = 2;  

The first one compiles indeed fine, because an assignment gets evaluated to the new value. So, if b is true, it will cause to be both x and y equal to 1. The second one is like saying: x = 1 = 2. So, yes, to fix this compiler error, add paratheses to your statement:

x = (b ? 1 : (y = 2));  // Outer () are not needed, but is clearer, IMHO.

Longer:

First of all, operator precedence in Java says that the assignment operators have lower priority than the conditional ternary operator. This means that your second expression is equivalent to:

x = (b ? 1 : y) = 2;

As you can see, this looks plain wrong. Indeed, JLS §15.26 says this:

There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a.

The result of the first operand of an assignment operator must be a variable, or a compile-time error occurs. (This explains the compile time error you face)

At run time, the result of the assignment expression is the value of the variable after the assignment has occurred. The result of an assignment expression is not itself a variable.

Applying right-associativity:

x = ((b ? 1 : y) = 2);

Finally we can see why this generates a compiler error: the result of a ternary conditional operator is not a variable (which is actually not in the JLS as far as I can find, however the compiler tells you in a simple test case like this one: https://ideone.com/kMr7Xv).

OTHER TIPS

See "Java operator precedence". Meanwhile, use:

x = (b ? 1 : (y=2)); 

Java operator precedence is as follows

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

here ternary comes before assignment operation. so your statement will be like this

x= ( ternary evaluation )= assignment value

if you still want set value for y , when b is false, you may use () for 'y=2' bring inside ternary evaluation.

x = b ? 1 : (y=2);

Brother, try putting expressions in brackets.

X= (b? 1 : (y=2));

this will work fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top