Is Integer Immutable

JavaImmutabilityMutable

Java Problem Overview


I know this is probably very stupid, but a lot of places claim that the Integer class in Java is immutable, yet the following code:

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

Executes without any trouble giving the (expected) result 6. So effectively the value of a has changed. Doesn't that mean Integer is mutable? Secondary question and a little offtopic: "Immutable classes do not need copy constructors". Anyone care to explain why?

Java Solutions


Solution 1 - Java

Immutable does not mean that a can never equal another value. For example, String is immutable too, but I can still do this:

String str = "hello";
// str equals "hello"
str = str + "world";
// now str equals "helloworld"

str was not changed, rather str is now a completely newly instantiated object, just as your Integer is. So the value of a did not mutate, but it was replaced with a completely new object, i.e. new Integer(6).

Solution 2 - Java

a is a "reference" to some Integer(3), your shorthand a+=b really means do this:

a = new Integer(3 + 3)

So no, Integers are not mutable, but the variables that point to them are*.

*It's possible to have immutable variables, these are denoted by the keyword final, which means that the reference may not change.

final Integer a = 3;
final Integer b = 3;
a += b; // compile error, the variable `a` is immutable, too.

Solution 3 - Java

You can determine that the object has changed using System.identityHashCode() (A better way is to use plain == however its not as obvious that the reference rather than the value has changed)

Integer a = 3;
System.out.println("before a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
a += 3;
System.out.println("after a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));

prints

before a +=3; a=3 id=70f9f9d8
after a +=3; a=6 id=2b820dda

You can see the underlying "id" of the object a refers to has changed.

Solution 4 - Java

To the initial question asked,

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

Integer is immutable, so what has happened above is 'a' has changed to a new reference of value 6. The initial value 3 is left with no reference in the memory (it has not been changed), so it can be garbage collected.

If this happens to a String, it will keep in the pool (in PermGen space) for longer period than the Integers as it expects to have references.

Solution 5 - Java

Yes Integer is immutable.

A is a reference which points to an object. When you run a += 3, that reassigns A to reference a new Integer object, with a different value.

You never modified the original object, rather you pointed the reference to a different object.

Read about the difference between objects and references here.

Solution 6 - Java

Immutable does not mean that you cannot change value for a variable. It just means that any new assignment creates a new object ( assigns it a new memory location) and then the value gets assigned to it.

To understand this for yourself, perform Integer assignment in a loop ( with integer declared outside the loop ) and look at the live objects in memory.

The reason why copy constructor is not needed for immutable objects is simple common sense. Since each assignment creates a new object, the language technically creates a copy already, so you do not have to create another copy.

Solution 7 - Java

> "Immutable classes do not need copy constructors". Anyone care to explain why?

The reason is that there is rarely any need to copy (or even any point in copying) an instance of a immutable class. The copy of the object should be "the same as" the original, and if it is the same, there should be no need to create it.

There are some underlying assumptions though:

  • It assumes that your application does not place any meaning on the object identity of instances of the class.

  • It assumes that the class has overloaded equals and hashCode so that a copy of an instance would be "the same as" the original ... according to these methods.

Either or both of those assumptions could be false, and that might warrant the addition of a copy constructor.

Solution 8 - Java

This is how I understand immutable

int a=3;    
int b=a;
b=b+5;
System.out.println(a); //this returns 3
System.out.println(b); //this returns 8

If int could mutate, "a" would print 8 but it does not because it is immutable, thats why it is 3. Your example is just a new assignment.

Solution 9 - Java

I can make clear that Integer (and other of its creed like Float, Short etc) are immutable by simple sample code:

> Sample Code

public class Test{
	public static void main(String... args){
		Integer i = 100;
		StringBuilder sb = new StringBuilder("Hi");
		Test c = new Test();
		c.doInteger(i);
		c.doStringBuilder(sb);
		System.out.println(sb.append(i)); //Expected result if Integer is mutable is Hi there 1000
	}
	
	private void doInteger(Integer i){
		i=1000;
	}
	
	private void doStringBuilder(StringBuilder sb){
		sb.append(" there");
	}

}

> Actual Result

The result comes to he Hi There 100 instead of expected result (in case of both sb and i being mutable objects) Hi There 1000

This shows the object created by i in main is not modified, whereas the sb is modified.

So StringBuilder demonstrated mutable behavior but not Integer.

So Integer is Immutable. Hence Proved

> Another code without only Integer:

public class Test{
	public static void main(String... args){
		Integer i = 100;
		Test c = new Test();
		c.doInteger(i);
		System.out.println(i); //Expected result is 1000 in case Integer is mutable
	}
	
	private void doInteger(Integer i){
		i=1000;
	}
	

}

Solution 10 - Java

public static void main(String[] args) {
	// TODO Auto-generated method stub

	String s1="Hi";
	String s2=s1;
	
	s1="Bye";

	System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
	System.out.println(s1); //Bye
	
	Integer i=1000;
	Integer i2=i;
	
	i=5000;

	System.out.println(i2); // 1000
	System.out.println(i); // 5000
	
	int j=1000;
	int j2=j;
	
	j=5000;

	System.out.println(j2); // 1000
	System.out.println(j); //  5000
	
	
	char c='a';
	char b=c;
	
	c='d';

	System.out.println(c); // d
	System.out.println(b); // a
}

Output is :

Hi Bye 1000 5000 1000 5000 d a

So char is mutable , String Integer and int are immutable.

Solution 11 - Java

Copy and run this code,I hope this will answer all your doubts

private static void wrapperClassDemo() {
	//checking wrapper class immutability using valueOf method
	//We can create wrapper class by using either "new" keyword or using a static method "valueOf()"
	//The below Example clarifies the immutability concept of wrapper class in detail
	//For better understanding just ciopy the below code to the editor and run
		
	Integer num1 =Integer.valueOf(34);  // i'm passing the 34 as the parameter to the valueOf method
	System.out.println("value assigned to num1 is : "+num1);
	System.out.println("Printing the hashcode assigned to store the \" num1 \"value in memory: "+System.identityHashCode(num1));
		
	Integer num2 =Integer.valueOf(34);
	System.out.println("value assigned to num2 is : "+num2);
	System.out.println("Printing the hashcode assigned to store the \" num2 \"value in memory: "+System.identityHashCode(num2));
		
	/*Now u can notice both the hashcode value of num1 and num2 are same. that is because once you created the num1 with the value 34 an object is 
	 * created in the heap memory. And now You are passing the value  same as num1 to the num2 .Now JVM Checks the same value is present in the heap Mmeomry
	 * If present the reference variable(in this example it is num2) will  be pointed to the same address where the object num1 is stored so u get the same hashcode		 */
		 
		
	num2++; // You can use num2 = 35 as both are same; 
	System.out.println("\nvalue assigned to num2 is : "+num2);
	System.out.println("Printing the hashcode of  \" num1 \": "+System.identityHashCode(num1) + "\nPrinting the hashcode of  \" num2 \": "+System.identityHashCode(num2));
	System.out.println("As now you can notice the hashcode has changed for num2 ,That is because now a new object is created for num2 and it is referencing the new object");
		
	//Again i'm incrementing num2
	System.out.println("\nBefore incremeting  the hashcode of  \" num2 \" is: "+System.identityHashCode(num2));
	num2++; // You can use num2 = 36 as both are same;
	System.out.println("After incremeting  the hashcode of  \" num2 \" is: "+System.identityHashCode(num2));
	//now the hashcode value of num2 is changed ,again new object is created for the updated value and num2 is referencing new object ,and old object will be garbage collected
		
	System.out.println("\n Thus the CONCLUSION is Wrapper objects are immutable ,They only create new object and refernce the new object ,They won't modify the present object ");
	System.out.println("This is applicable for Strings also");

Solution 12 - Java

Something to hold in mind is that there is now a cache for Integer values. It sometimes saves developers from the mistake of using == instead of .equals() when changing from int to Integer. Not always though. When you instantiate a new Integer, there will be a new instance created. So Integers are not only immutable, but also semi static.

	Integer a = 3;
	Integer b = 3;
	Integer c = new Integer(3);
	b = b + 1;
	b = b - 1;

	System.out.println("a-id: " + System.identityHashCode(a));
	System.out.println("b-id: " + System.identityHashCode(b));
	System.out.println("c-id: " + System.identityHashCode(c));
	System.out.println("a == b: " + (a == b));
	System.out.println("a == c: " + (a == c));
	System.out.println("a eq c: " + (a.equals(c)));    

Gives the printout:

a-id: 666988784
b-id: 666988784
c-id: 1414644648
a == b: true
a == c: false
a eq c: true

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionK.SteffView Question on Stackoverflow
Solution 1 - JavaTravis WebbView Answer on Stackoverflow
Solution 2 - JavaMark ElliotView Answer on Stackoverflow
Solution 3 - JavaPeter LawreyView Answer on Stackoverflow
Solution 4 - JavaHarshaView Answer on Stackoverflow
Solution 5 - JavaAndyView Answer on Stackoverflow
Solution 6 - Javauncaught_exceptionsView Answer on Stackoverflow
Solution 7 - JavaStephen CView Answer on Stackoverflow
Solution 8 - JavaNdhetiView Answer on Stackoverflow
Solution 9 - JavaAshutosh NigamView Answer on Stackoverflow
Solution 10 - Javaözgür arslanView Answer on Stackoverflow
Solution 11 - Javasree vishnuView Answer on Stackoverflow
Solution 12 - JavaOlav HoltenView Answer on Stackoverflow