Java Ternary operator syntax [duplicate] - java

This question already has answers here:
Ternary operator, syntax error when using assignment
(4 answers)
Closed 8 years ago.
I have the following piece of code. This is how I understand it.
In the first case, the ternary operator returns the value of y because x=4 and the print statement prints 5, as expected.
In the 2nd case, the ternary operator first assigns the value of y to x and then returns that value. Again, it prints 5, as expected.
In the 3rd case, the ternary operator has x=y to the left of the : and x=z to the right of the :. I would expect this to behave much like the 2nd case. However, this statement does not even compile.
Any help in understanding this will be much appreciated.
public class Test {
public static void main(String[] args) {
int x = 4;
int y = 5;
int z = -1;
x = (x == 4) ? y : z; // compiles and runs fine
System.out.println(x + " " + y + " " + z);
x = (x == 4) ? x = y : z; // compiles and runs fine
System.out.println(x + " " + y + " " + z);
x = (x == 4) ? x = y : x = z; // Does not compile
System.out.println(x + " " + y + " " + z);
}
}

Assignment has lower precedence than a ternary expression, so this expression:
(x==4)?x=y:x = z;
can be thought of as:
((x==4)?x=y:x) = z;
Which obviously won't compile because you can't assign a value to something that isn't a variable.

Add parenthesis to control the order of evaluation
x = (x == 4) ? (x = y) : (x = z); // Does compile.
Note the above is equivalent to
if (x == 4) {
x = (x = y);
} else {
x = (x = z);
}
Which will (as a side effect) of assigning a value to x assign the value assigned to x to x. In other words, your ternary is equivalent to
x = (x == 4) ? y : z;
or
if (x == 4) {
x = y;
} else {
x = z;
}
The ternary is specified in JLS-15.25. Conditional Operator ? :.

Related

Java Unexped Outputs From Pre-Increment

I am trying to figure out why the following code gives two different results
I tried the followingL
int x = 4, y = 4;
System.out.println(x + --x);
System.out.println(--y + y);
And It outputs 7 6. From my knowledge, preincrement has a higher precendence than addition so it should decrease the value of x/y regardless of it's value in the expression but this is clearly not the case. Can anyone please explain this to me?
System.out.println(x + --x);
System.out.println(--y + y);
This can be re-written as:
x + --x => x + (x = x-1) => 4 + 3 = 7
--y + y => (y = y-1) + y (y here is already decreased in value) = 3 + 3 = 6

How increment and decrement with if condition

I have this code:
class Example {
public static void main(String args[]) {
int x = 99;
if (x++ == x) {
System.out.println("x++==x : " + x);
}
if (++x == x ) {
System.out.println("++x==x : " + x); // ++x == x : 101
}
if (x == x++) {
System.out.println("x==x++ : " + x); //x==x++ : 102
}
if (x == ++x) {
System.out.println("x==++x : " + x);
}
if (++x == ++x) {
System.out.println("++x==++x : " + x);
}
if (x++ == x++) {
System.out.println("x++==x++ : " + x);
}
if (++x == x++) {
System.out.println("++x==x++ : " + x); // ++x==x++ : 109
}
}
}
and this is the output -->
++x==x : 101
x==x++ : 102
++x==x++ : 109
I want to figure out how the java compiler handles this code. I could figure out how it came up with this part of the output:
++x==x : 101
x==x++ : 102
But I couldn't with this part of the output:
++x==x++ : 109
How does this code work? And most importantly how does the last output work?
You just need to know 3 things and use logic to put it together:
x++ means: "Increment x, but the expression's value is what x was before you increment".
++x means: "Increment x, and the expression's value is what x is after you increment".
Things resolve left to right for the == operator. So, java 'resolves' the thing on the left, then the thing on the right, then does the calculation.
Thus, given: ++x==x++, and let's say x starts out as 107. Let's break it down:
First, resolve the left side, which is ++x. To do that, increment (x is now 108), then resolve the expression as the value after increment. So, the left hand side is 108.
Next resolve right side, which is x++. To do that, increment (x is now 109), then resolve the expression as the value before increment. So, the right hand side is 108.
Now do the operation. 108 == 108. That's true, so the if 'passes', and the result is printed. Given that x is now 109, it would print "++x==x++ : 109".
Which is exactly what it does.
++x is pre-increment
x++ is post-increment
Even if your condition gets a false, the incrementing will be done.

Using assignment operator inside of expression

Running this code will return 11 while I was expecting 20. Why is that so?
int x = 1;
int y = x + (x = 10);
System.out.println(y);
Evaluation is from left to right. So
int y = x + (x = 10);
is (with x initially 1):
int y = 1 + 10;
Putting the assignment in () doesn't make it come first. It just ensures that it's a valid expression, since y = x + x = 10 would be y = (x + x) = 10 which would require assigning to something (x + x) that wasn't a variable.
If you want 20, put the assignment first:
int y = (x = 10) + x;
Of course, the vast majority of the time, it's best to avoid these kinds of side-effects and assign x a value outside the expression, breaking the expression up if necessary. Assignment-within-expression can be useful sometimes (particularly while ((blah = getNextBlah()) != null) sort of things), but only in limited situations.

Unboxing int value using Integer Class

In this circumstance what is the value of variable y after the first two statements? I'm assuming it's Integer 7 but my book says automatic unboxing of objects only occurs with relational operators < >". I'm a little confused how variable Integer y gets it's value. Does any unboxing occur in newInteger(x)?
Integer x = 7;
Integer y = new Integer(x);
println( "x == y" + " is " + (x == y))
Unboxing happens when the compiler is certain that you wish to compare values. Using == can compare the Objects and therefore give false because == is a valid operation between objects. With < and > there is no concept of Object < OtherObject so it is certain that you mean numerically.
public void test() {
Integer x = 7;
Integer y = new Integer(x) + 1;
System.out.println("x == y" + " is " + (x == y));
System.out.println("x.intValue() == y.intValue()" + " is " + (x.intValue() == y.intValue()));
System.out.println("x < y" + " is " + (x < y));
System.out.println("x.intValue() < y.intValue()" + " is " + (x.intValue() < y.intValue()));
}
x == y is false
x.intValue() == y.intValue() is true
x < y is true
x.intValue() < y.intValue() is true
In this circumstance what is the value of variable y after the first two statements?
The value of the variable y is a reference to an Integer object containing the value 7.
Integer x = 7;
In this case, the int literal 7 is automatically boxed into the Integer variable x.
Integer y = new Integer(x);
This involves an automatic unboxing of the Integer variable x into an int (temporary) variable, which is passed to the Integer constructor. In other words, it is equivalent to:
Integer y = new Integer(x.intValue());
After this statement, y points to a new object that is different than x but containing the same int wrapped value.

Incrementing and Decrementing changing object value

Can anyone tell me the reason for the change in output.
public class Demo {
public void demo()
{
Integer y = 567;
Integer x = y;
System.out.println(x + " " + y);
System.out.println(y == x);
y++;
System.out.println(x + " " + y);
System.out.println(y == x);
y--;
System.out.println(x + " " + y);
System.out.println(y == x);
}
public static void main(String args[])
{
Demo obj = new Demo();
obj.demo();
}
}
OUTPUT:
567 567
true
567 568
false
567 567
False
Here why i'm getting the final false.
You are using Integer which is an immutable object.
Basically your code is
y = new Integer(y.intValue() + 1);
and
y = new Integer(y.intValue() - 1);
Therefore you're creating two new Integer objects that are not the same (==) as the previous objects.
This behaviour is called autoboxing in Java.
Change your
Integer y = 567;
Integer x = y;
to
int y = 567;
int x = y;
and the suprprising behavior will be gone. My guess is that you have stumbled upon Java's implicit autoboxing of primitive values into wrapper objects, and are lead to believe that you are directly manipulating the numbers.
This is because the compiler does this internally:
y--
means:
int _y = y.intValue();
_y--;
y = Integer.valueOf(_y);
Therefore, y is has a new Integer instance. You are doing Object reference check (when using ==) and not value equality check.
Use equals() method to evaluate 2 values.
Integer y = 567; // y=567
Integer x = y; // x is equal to y object
System.out.println(x + " " + y); // out put x and y so obviously x and y are 567
System.out.println(y == x); // here x and y are in same reference. so this x==y is true and out put is true.
y++; // increment y by 1. then y=568
System.out.println(x + " " + y); // now x= 567 and y= 568
System.out.println(y == x);// now x not equals to y then false will print
y--; // again decrement y value
System.out.println(x + " " + y); // again x and y are same 567
System.out.println(y == x);// here y.value == x.value but x and y object wise not equal since object x and y are referring deference points
Because x and y are referring to 2 different objects.
y--;
This first unboxes y to int than decrements it and than boxes it to Integer. And this new boxed integer is referring to a different memory location.
Ideally, on wrapper classes, its better to call equals method on wrapper object rather than == operator.
y == x checks for content-equality, that is, whether they pointed to the same object, not whether the object they pointed to contains the same int. Especially when x, y >= 128.
Use
y.equals(x);
or
(int) y == (int) x
or declare x and y as int instead.
Note that auto-unboxing doesn't happen in Integer == Integer or Integer != Integer.
When you use primitive int instead of the Integer. The final output would be true.
However when you use Integer class, these are Objects. If you use the equals method the final output would be true.
Even, if you create
Integer a = new Integer(1000);
Integer b = new Integer(1000);
a==b - false
but for
Integer a = new Integer(1);
Integer b = new Integer(1);
a==b - is true
In java there is a cache of small integers: -127 to 128. All other integers are newly created objects and they can not be equals.

Categories

Resources