What does the ++ operator do to an Integer?

Viewed 1654

Following test case will pass:

@Test
public void assignWrapperTest() {
    System.out.printf("\nassign - %s\n", "wrapper");

    Integer a = 1000;
    Integer b = a;
    System.out.printf("a = %d, b = %d\n", a, b);
    Assert.assertEquals(a, b);
    Assert.assertSame(a, b); // a, b are the same object,

    a++;
    System.out.printf("a = %d, b = %d\n", a, b);
    Assert.assertNotEquals(a, b);
    Assert.assertNotSame(a, b); // a, b are not the same object, any more,
}

So:

  • a is changed by ++.
  • b remains the same.

The questions are:

  • b = a just assign the reference value right, they refer to the same object, at this point there is only one object, right?
  • What ++ operator does on an Integer?
    Since Integer is immutable, does this means ++ created a new Integer object, and assigned it back to the original variable automatically? If that's the case, does that means a now point to a different object?
  • There are 2 objects now? And b still point to the original one ?
5 Answers
a++;

Because a is an Integer, this is the same as:

a = Integer.valueOf(a.intValue() + 1);

does this means ++ created a new Integer object

Maybe, but not necessarily: Integer.valueOf will reuse a cached value; a new value will only be created if outside the cached range (which is at least -128..127).

If we look at the Byte code of a++; It looks something like below:

    9: aload_1
   10: invokevirtual #22                 // Method java/lang/Integer.intValue:()I
   13: iconst_1
   14: iadd
   15: invokestatic  #16                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   18: astore_1

So the instructions are like getting the intValue() of a then increment it then call Integer#valueOf on the incremented value and Integer#valueOf create a new object.

  • That is correct. That is the way the JVM works.
  • Yes. a++ effectively does a=a+1 (ignoring the logic to convert it to an Integer). The expression a+1 evaluates to a new int, and that gets assigned to a.
  • Affirmative. The value of b has not been touched by the previous operations, and hence it's still pointing at the same object.

Yes.

Integer objects are immutable. But, their references held by are mutable. Integer classes, cache data and reuse them.

Let's see what's happening in your code.

Integer a = 1000; // Let's say it creates a memory block of 4 bytes in heap with address reference &addr_of_val_1000;

Integer b = a; // now, b points to address reference &addr_of_val_1000;

a++; // this creates/fetches a new value 1001 in/from heap with new address reference &addr_of_val_1001; and assignes to variable a

So,

a = 1001 and b = 1000 are not equal. &addr_of_val_1000 != &addr_of_val_1001 (their references are not same anymore)

But, if you add,

b++;

or

b = Integer.valueOf(1001)

before your check, they will be equal and same again.

The key point here is that Integer is immutable.

  1. If the operand is mutable, like an int, ++ operator just add 1 to the original value in place.

  2. For Integer it is different. By a++, a new instance of Integer is created, and the value of it comes from adding a 1 to the original Integer object which both a and b are pointing to, and then a is re-assigned to this new object. b still refers to the original Integer object, so a and b are not the same now.

Related