Reputation: 7226
I know the usual reasons that apply to general immutable classes, viz
However, wrapper classes represent primitive types, and primitive types are mutable. So why aren't wrapper classes mutable?
Upvotes: 27
Views: 31349
Reputation: 72294
However, wrapper classes represent primitive types, and primitive types (except String) are mutable.
No they're not (and String isn't a primitive type). But since primitive types aren't objects anyway, they can't really be called mutable / immutable in the first place.
Regardless, the fact that wrapper classes are immutable is a design decision (a good one IMO.) They could have just has easily been made mutable, or mutable alternatives provided too (indeed several libraries provide this, and other languages do by default.)
Upvotes: 4
Reputation: 951
The wrapper classes are immutable because it just makes no sense to be mutable.
Consider following code:
int n = 5;
n = 6;
Integer N = new Integer(n);
At first, it looks straightforward if you can change the value of N, just like you can change the value of n.
But actually N is not a wrapper to n, but a wrapper to 6! Look at the following line again:
Integer N = new Integer(n);
You are actually passing the value of n, which is 6, to N. And since Java is pass-by-value, you cannot pass n into N, to make N a wrapper to n.
So, if we did add a set method to the wrapper:
Integer N = new Integer(n);
N.setValue(7);
print(N); // ok, now it is 7
print(n); // oops, still 6!
The value of n will not be changed and that will be confusing!
Conclusion:
wrapper classes are wrappers of values, not wrappers of the variables.
it will be confusing if you did add a set method.
if you know it is a wrapper of a value, you will no longer ask for a set method. For example, you will not do "6.setValue(7)".
it's impossible to make a wrapper to a variable in Java.
Upvotes: 4
Reputation: 3756
For example, consider the following java program:
class WhyMutable
{
public static void main(String[] args)
{
String name = "Vipin";
Double sal = 60000.00;
displayTax(name, sal);
}
static void displayTax(String name, Double num) {
name = "Hello " + name.concat("!");
num = num * 30 / 100;
System.out.println(name + " You have to pay tax $" + num);
}
}
Result: Hello Vipin! You have to pay tax $18000.0
This is the case with pass by reference of wrapper class parameters as well. And, if strings and wrapper classes are non-final, anybody can extend those classes and write their own code to modify the wrapped primitive data. So, in order to maintain Data Integrity, the variables which we are using for data storage must be read-only,
i.e., Strings and Wrapper classes must be final & immutable and “pass by reference” feature should not be provided.
Upvotes: 0
Reputation: 7061
The primitive types are mutable, but they are not shareable - that is no two sections of code will ever be referring to the same int variable (they are always passed by value). So you can change your copy and no one else sees the change, and vice versa. As Phillip shows in his answer, that would not be the case with mutable wrapper classes. So my guess is that they had a choice when the wrapped the primitive data types between:
matching the fact that you can change the value of a primitive type,
versus
matching the fact that primitive types can be passed around and no changes by a user will be seen by any other user of the data.
And they chose the latter, which required immutability.
Upvotes: 0
Reputation: 81179
Any object instance which has any mutable aspects must have a unique identity; otherwise, another object instances which at one moment happened to be identical in every way except for its identity might at some other moment be different in its mutable aspect. In many cases, though, it's useful for types not to have an identity--to be able to pass a "4" without having to worry about which "4" one is passing. While there are times when it may be helpful to have a mutable wrapper of a primitive or immutable type, there are many more times when it's useful to have a type where all instances that hold the same data at some moment in time may be regarded as interchangeable.
Upvotes: 3
Reputation: 533530
There are mutable, thread safe wrappers as well for some types.
AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicLong
AtomicLongArray
AtomicReference - can wrap a String.
AtomicReferenceArray
Plus some exotic wrappers
AtomicMarkableReference - A reference and boolean
AtomicStampedReference - A reference and int
Upvotes: 15
Reputation: 69663
Here is an example where it would be quite bad when Integer would be mutable
class Foo{
private Integer value;
public set(Integer value) { this.value = value; }
}
/* ... */
Foo foo1 = new Foo();
Foo foo2 = new Foo();
Foo foo3 = new Foo();
Integer i = new Integer(1);
foo1.set(i);
++i;
foo2.set(i);
++i;
foo3.set(i);
Which are the values of foo1, foo2 and foo3 now? You would expect them to be 1, 2 and 3. But when Integer would be mutable, they would now all be 3 because Foo.value
would all point to the same Integer object.
Upvotes: 12
Reputation: 298908
For your info: if you want mutable holder classes, you can use the Atomic* classes in the java.util.concurrent
package, e.g. AtomicInteger
, AtomicLong
Upvotes: 6
Reputation: 1500815
However, wrapper classes represent primitive types, and primitive types (except String) are mutable.
Firstly, String isn't a primitive type.
Secondly, it makes no sense to talk about the primitive types being mutable. If you change the value of a variable like this:
int x = 5;
x = 6;
That's not changing the number 5 - it's changing the value of x
.
While the wrapper types could have been made mutable, it would have been annoying to do so, in my view. I frequently use readonly collections of these types, and wouldn't want them to be changeable. Very occasionally I want a mutable equivalent, but in that case it's easy enough to come up with one, or use the Atomic*
classes.
I find myself wishing that Date
and Calendar
were immutable far more often than I find myself wanting Integer
to be mutable... (Of course I normally reach for Joda Time instead, but one of the benefits of Joda Time is immutability.)
Upvotes: 34