Are Java wrapper classes really immutable?
Asked Answered
A

6

20

Java Wrapper classes are supposed to be immutable. This means that once an object is being created, e.g.,

Integer i = new Integer(5);

its value cannot be changed. However, doing

i = 6;

is perfectly valid.

So, what does immutability in this context mean? Does this have to do with auto-boxing/unboxing? If so, is there any way to prevent the compiler from doing it?

Thank you

Abrego answered 7/11, 2010 at 12:58 Comment(0)
U
26

i is a reference. Your code change the reference i to point to a different, equally immutable, Integer.

final Integer i = Integer.valueOf(5);

might be more useful.

Unloosen answered 7/11, 2010 at 13:1 Comment(0)
R
19

Immutable means that the object state cannot be changed. In your case you haven't changed the object new Integer(5), but you have changed the reference i to point to another object. Hope it is clear:)

Runagate answered 7/11, 2010 at 13:1 Comment(0)
L
15

The compiler autoboxes primitive values, this means that

Integer value = 6;

will be compiled as

Integer value = Integer.valueOf(6);

Integer.valueOf will return an Integer instance with the given value. In your case i will now reference the Integer(6) instead of the Integer(5), the Integer(5) object itself will not change.

To see this you can do following

Integer i = new Integer(5);//assign new integer to i
Integer b = i;//b refences same integer as i
i = 6;//modify i
System.out.println(i +"!="+b);

This will print 6!=5, if the integer instance had been modified it would print 6!=6 instead.

To clarify this is only meant to show how an assignment to Integer only modifies the reference and does not alter the Integer instance itself. As user @KNU points out it does not prove or show the immutability of Integer, as far as I can tell the immutability is only indirectly given by the lack of modifying methods in its API and the requirement that instances returned by Integer.valueOf have to be cached for a certain range.

Limy answered 7/11, 2010 at 13:24 Comment(5)
This is quite an interesting blog entry on primitive/object equality: marxsoftware.blogspot.com/2010/08/…Fornax
this example doesn't proves immutability of Integer in any way. "....if the integer instance had been modified it would print 6!=6 instead." OK how about repeating above test on know mutable object AtomicInteger??? it would still print 6!=5 ,throwing water on above argument.Breckenridge
Note: for above suggested test one needs to use i = new AtomicInteger(6); instead of i = 6;Breckenridge
@Breckenridge I added a clarification.Limy
the will be compiled as... thing was really enlightening for me. Until now I never cared to now how it actually works.GreatBreckenridge
B
6

The reason i = 6 works is that auto-boxing is intercepting and turning it into i = new Integer(6). Thus as @Peter said, you are now pointing at a new object.

Bertold answered 7/11, 2010 at 13:22 Comment(2)
Almost - it effectively turns it into Integer.valueOf(6). See this for more info: marxsoftware.blogspot.com/2010/08/…Fornax
Oops. My Bad :-) I had not actually bothered to look up exactly what it translated to.Bertold
M
0
Integer i = new Integer(5);
i++;                         // i  will become 6

where i++ is the same with i = new Integer( i.intValue() + 1);

Mcgregor answered 20/7, 2020 at 16:47 Comment(3)
Interesting does the Java compiler still recommend using ++? Swift got rid of it strictly += nowRaceme
@Greg Pricei I'm lazy, so i++ is shorter than i+=1 and cooler than i=i+1Mcgregor
Duracell De Monaco This is a nice read even if you haven't touched swift. :) #35158922Raceme
G
-1

All wrapper classes in java are immutable. We can't change the value of a wrapper class object once created, i.e., can't change the value wrapped inside the object. Because wrapper classes are used as object form of primitive data types and if they are mutable, data inconsistencies will occur in runtime. However, you can change the wrapper class reference variable to hold another object.

Gaunt answered 25/3, 2013 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.