7 Answers
7

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.)

@shrini1000, you have right as far it goes for memory allocation. But in Java you can not read/write directly from/to memory. Therefore as Jon Skeet wrote it make no sence to call primitives mutable or inmutable because of the way you must work with them.
–
Damian Leszczyński - VashSep 11 '12 at 13:38

6

@shrini1000: You agree that strings are immutable, right? But if you wrote String x = "hello"; x = "there"; that wouldn't make them mutable, would it? Changing the value of a variable isn't the same thing as making that value change itself.
–
Jon SkeetSep 11 '12 at 13:40

@bestsss: Well Calendar is a mixture of computation and state. That's half the problem. In Joda Time the two are separated, which is much better. Making an immutable type extend a mutable one breaks LSP IMO. Anything expecting to treat it like a normal Date using setTime etc will fail.
–
Jon SkeetSep 12 '12 at 16:03

Stamped and Markable suck though as there are no intrinsics for, esp. for the Markable, it'd be an awesome class if the bits in the reference/pointer were actually used. (Pointer/References may have some unused bits like in CMS uses them). Stamped can be implemeted as 32pointer+32int and take 64 bit CAS, or 64bit and 32bit and 128bit CAS, alas they allocate like mad.
–
bestsssSep 12 '12 at 15:20

No they're not (and String isn't a primitive). But since primitive types aren't objects anyway, they can't really be called mutable / immutable in the first place.

Regardless, the fact the wrapper classes are immutable is a design decision (a good one IMO.) Thye could have just has easily been made mutable, or mutable alternatives provided too (indeed several libraries provide this, and other languages do by default.)

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.

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.

The primitive types are mutable, but they are not shareable - that is no two objects will ever be referring to the same int variable (pass 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 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 other classes will be affected by operations performed on the data by a particular class. And they chose the latter.