An increment of an Integer variable does not affect another reference to the same object

I always understood static variables to share one instance whenever they were referenced. I wanted to put this to the test, but the results were different than I expected.

static Integer counter = 0; static Integer test = counter; public static void main(String args[]) { counter++; System.out.println("counter: " + counter); System.out.println("test: " + test); } 

exit:

counter: 1

test: 0

Since test links are counter , I thought that when I increment counter , then test will also increment automatically. However, it seems that test referencing 0 from somewhere, the question is, where?

+5
source share
5 answers

Since test links are counter

This assumption is incorrect. In Java, you cannot reference variables. What is stored in a variable is a value. This value can be either a primitive type value or a reference type value. In the case of primitives, the value is the value of the primitive. In the case of reference types

Reference values ​​(often only links) are pointers to these objects and a special null reference that is not related to the object.

IN

 int a = 0; int b = a; 

the variable a is evaluated to get the value 0 , and this value is stored in b .

IN

 Integer a = 0; Integer b = a; 

0 converted to Integer through Integer.valueOf(int) and the value, the reference to the Integer object, is stored in a . Then a is evaluated, creating the value of this reference for the Integer object, and that value is stored in b .

This is the same concept that was discussed in

In addition, the fact that static variables does not matter.

The only way is to update test manually, i.e.

 counter++; test = counter; 
+4
source

Here is my understanding.

  • Step 1:. When you say Integer counter = 0; what you are actually doing, Integer counter = new Integer(0); Here you create an Integer object whose value is 0 and counter indicates this.
  • Step 2: Integer test = counter;

    Now test also refers to the same Integer object we created in step 1.

  • Step 3:. This is the hard part. When you do counter++; In its main method, Java Auto-Boxing and Auto-Unpack functions implement the below code for you.

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

As an Integer class, immutable in Java, when the value increases from 0 to 1, the valueOf() method creates a new Integer object and stores the new value 1 in it instead of changing the value of the old object (see below for the implementation of the Java method valueOf () ). When you reference a new object using counter , it unlinked the old Integer object , whose value is 0. But the reference variable test still contains the old Integer object . This is why test prints the old value.

Java method valueOf () from Integer library class

 638 public static Integer More ...valueOf(int i) { 639 assert IntegerCache.high >= 127; 640 if (i >= IntegerCache.low && i <= IntegerCache.high) 641 return IntegerCache.cache[i + (-IntegerCache.low)]; 642 return new Integer(i); //See, new object is created here. 643 } 

See below for a detailed schematic explanation.

A solid line implies that the reference variable is still holding the object.

The dashed line means that the reference variable no longer holds the object.

enter image description here

+2
source

test does not reference counter . It has the same initial meaning. int is primitive.

+1
source

test not a pointer to counter : you set its value to equal to the counter initially, but any subsequent changes to counter will not be displayed in the value of test .

If you want to have two references to the same mutable value, you can use something like AtomicInteger :

 static AtomicInteger counter = new AtomicInteger(0); static AtomicInteger test = counter; public static void main(String args[]) { counter.incrementAndGet(); System.out.println("counter: " + counter); System.out.println("test: " + test); } 

Conclusion:

 counter: 1 test: 1 
0
source

You need to distinguish between the primitive and the link object. The integer is not primitive per-se, but they have special properties due to boxing . What you have is primitive due to intValue () , therefore it gets the initial value (it no longer has relationship to the counter).

Well ... for the record "downgraders": the OP changed its fields from "int" to "Integers", and so my original answer was wrong.

-2
source

All Articles