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.)
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.)
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
Videos
Any type which doesn't give you any means to change the data within it is immutable - it's as simple as that. Yes, all the primitive wrapper types are immutable1, as is String. UUID, URL and URI are other examples.
Although Calendar and Date in the built-in Java API are mutable, many of the types within Joda Time are immutable - and to my mind, this is one reason why Joda Time is easier to work with. If an object is immutable, you can keep a reference to it somewhere else in your code and not have to worry about whether or not some other piece of code is going to make changes - it's easier to reason about your code.
1 by which I mean java.lang.Integer etc. As noted elsewhere, the Atomic* classes are mutable, and indeed have to be in order to serve their purpose. There's a difference in my mind between "the standard set of primitive wrapper classes" and "the set of classes which wrap primitive values".
You can write your own mutable wrapper class very easily:
public class MutableInteger
{
private int value;
public MutableInteger(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
public void setValue(int value)
{
this.value = value;
}
}
So as you can see, there's nothing inherently immutable about wrapper classes - it's just that the standard ones were designed to be immutable, by virtue of not providing any way to change the wrapped value.
Note that this allows for the same object to be used repeatedly when boxing, for common values:
Integer x = 100;
Integer y = 100;
// x and y are actually guaranteed to refer to the same object
Integer a = 1000;
Integer b = 1000;
// a and b *could* refer to the same object, but probably won't
Before Java 5, all the primitive wrapper classes were immutable.
However, the atomic wrapper classes introduced in Java 5 (AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference<V>) are mutable.
The way I understand wrapper classes is they are used to convert primitive data types into objects so you can store them in Collection classes. I also believe that this happens automatically on backend by the compiler through a process called autoboxing.
To me, someone with no real world programming experience, I find myself wondering why use primitives at all?
The wrapper classes are much more interesting because you get methods to do things, where primitives are boring. Why not just use wrapper classes for everything? Is that even possible?
My gut tells me that someone is going to say primitives are faster, but is that a valid argument considering the speed of computers today?