Incrementing and Decrementing changing object value - java

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.

Related

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.

Curious on what this function is doing

Can someone tell me what is this function doing? I just know that it returns the sum of x + y, but I want to know why. Thanks
public static int f(int x, int y){
while( y > 0){
x = x + 1;
y = y - 1;
}
return x;
}
There are two cases:
First case: y <= 0
Because the while loop is false, it just returns x ("it skips the part")
Second case: y > 0
Because the while loop is true, it returns x + y (x + number of iterations)
The number of iterations is the value of y because with every iteration, y will be decreased by 1 until y = 0.
The loop starts at the value of y, and decrements it on each iteration, stopping when y gets to zero.
For each of these iterations, 1 is added to x. Therefore, for 'unit' of y, a 'unit' is added to x.
Edit As noted in the comments, the function will not return the sum of the two numbers if y is less then zero, since the loop will not execute at all.
Addition can be viewed as a series of increments. That's what this function does. It increments x y times and returns the result which is x + y. It is assumed that y is a natural number.

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.

Java Ternary operator syntax [duplicate]

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 ? :.

what is the priority for static block in java?

public class Static
{
static
{
int x = 5;
}
static int x,y;
public static void main(String args[])
{
x--; myMethod();
System.out.println(x + y + ++x);
}
public static void myMethod()
{
y = x++ + ++x;
}
}
Could you please somebody help me here why it is displaying out put is 3?
static
{
int x = 5;
}
You redeclare x here, making it a locally scoped variable (not a class member). This assignment will have no affect whatsoever, regardless of when it is run.
Now, you asked about the static block and that's what I answered. If you are confused about why a value of 3 is outputted even assuming that assignment doesn't take place, then this becomes a question about the increment operators (x++ and ++x).
Full explanation
I like Paulo's explanation quite a bit but let's just see if we can simplify the code. To start, let's forget about making x and y a static field (making them local, initialized to the default for a static int: 0) and inline myMethod():
int x = 0, y = 0;
x--;
y = x++ + ++x;
System.out.println(x + y + ++x);
First we should eliminate complex expressions. We can do that by extracting each sub-expression into a temporary variable in the correct order (expressions are evaluated left-to-right):
int x = 0, y = 0;
x--;
int yOperand1 = x++;
int yOperand2 = ++x;
y = yOperand1 + yOperand2;
int resultOperand1 = x;
int resultOperand2 = y;
int resultOperand3 = ++x;
int result = resultOperand1 + resultOperand2 + resultOperand3;
System.out.println(result);
Now we can label the value of x, y and any temporary variables at each step:
int x = 0, y = 0; //x: 0 y: 0
x--; //x: -1 y: 0
int yOperand1 = x++; //x: 0 y: 0 yOperand1: -1
int yOperand2 = ++x; //x: 1 y: 0 yOperand1: -1 yOperand2: 1
y = yOperand1 + yOperand2; //x: 1 y: 0
int resultOperand1 = x; //x: 1 y: 0 resultOperand1: 1
int resultOperand2 = y; //x: 1 resultOperand1: 1 resultOperand2: 0
int resultOperand3 = ++x; //x: 2 resultOperand1: 1 resultOperand2: 0 resultOperand3: 2
int result = resultOperand1 + resultOperand2 + resultOperand3; //result: 3
System.out.println(result);
Your static block has a local variable named x, it does not change the static variable with the same name.
In general, static { ... } blocks will be merged by the compiler with the initializers of static variables in the order they are in the code, and executed on class initialization. (In bytecode, this is a static <clinit> method.)
In your program the following occurs:
the static variables x and y are initialized with their default values (0).
the static block with its local variable is executed, this has no effect on the rest of the program.
the main method will execute.
it sets x = -1.
it invokes myMethod().
myMethod will twice increment x (from -1 to 0 to 1), and set y to 0 (the value before the first incrementing + the value after the second one).
it adds x (1), y (0) and the value after increasing x again (2), and prints the result (3).
Static.x starts with the value 0 since {int x = 5;} creates a new variable that is only visible within the static block. Since that x is never used it does nothing. If you removed it you should be able to trace through and see why your answer is what it is. :)
What you want is either to make the contents of the static block an assignment rather than a declaration ( ie static{ x = 5; }) or to assign x the value 5 at declaration static int x = 5;.

Categories

Resources