23

Are all primitive wrapper classes in Java immutable objects? String is immutable. What are the other immutable objects?

Koekiebox
  • 5,793
  • 14
  • 53
  • 88
Jothi
  • 14,720
  • 22
  • 68
  • 93
  • possible duplicate of [Immutable Classes](http://stackoverflow.com/questions/5124012/immutable-classes) – Howard May 29 '11 at 06:59

4 Answers4

24

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
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Right about Joda Time. This is also one of the reasons why it's being considered as the base for a new time API in the JDK. – Arjan Tijms May 29 '11 at 07:01
  • @arjan: Actually JSR 310 is somewhat different from Joda Time, but is being led by the same person. And yes, immutability is one aspect of it :) – Jon Skeet May 29 '11 at 07:09
  • You're right, it's somewhat different indeed, but the way I understood it it's not completely different. That's why I mentioned it's the *base* of a new implementation ;) – Arjan Tijms May 29 '11 at 08:57
  • 4
    I know this thread has been answered 2 years ago but I need to know for the sake of my confused mind. @JonSkeet why did you say that in `Integer a = 1000` and `Integer b = 1000` a and b could refer to the same object but probably not? while in `Integer x = 100` and `Integer y = 100` x and y are guaranteed to refer to the same object? – Bnrdo Apr 12 '13 at 02:28
  • I'm also curious. Jon, what is the difference between the pairs (x, y) and (a, b) in your example? Is it a typo? Surely the variable names / values don't make a difference? – Graham Griffiths Aug 02 '13 at 13:16
  • 2
    @GrahamGriffiths: The values do. See the last few paragraphs of http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 – Jon Skeet Aug 02 '13 at 13:17
  • @onepotato I know your comment is an year old!, But just for the sake of completeness or the next reader, It is because some JVMs have values -127 to +128 cached and and same references are returned for values in this range. see: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(int) – gkns Mar 30 '14 at 14:44
  • 1
    @gkns: Not *some* JVMs... *all* JVMs that follow the language specification, for values in -128 to +127 (not the other way round). However, some JVMs may cache *more* values than that. – Jon Skeet Mar 30 '14 at 14:45
  • *Any type which doesn't give you any means to change the data within it is immutable.* Is it as simple as that? People often refer to immutability in terms of thread-safety, but that's dependent on more than whether an object is externally modifiable. – shmosel Aug 24 '17 at 07:17
  • @shmosel: I would say that immutability is separate from thread-safety - literally, "immutable" means "unchangeable" which has nothing to do with thread-safety. Immutable types are usually *naturally* thread-safe, but not necessarily. There's still a bit of a spectrum of immutability - a type which caches the generated hash code is sort of "externally immutable" but can mutate its internal state in an undetectable manner (without a debugger/reflection etc). – Jon Skeet Aug 24 '17 at 07:44
  • 1
    The Java Language Specification indeed *requires* that the `Integer` instances representing integer values between -128 and 127 are guaranteed to be the same if they represent the same integer value. See [JLS § 5.1.7](https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.7). – MC Emperor Mar 01 '19 at 09:52
11

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.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • 1
    While I certainly agree that AtomicInteger etc are mutable, I don't think those are normally referred to as "primitive wrapper classes" in the sense that they're not quite as strongly associated with the primitive types as Integer etc... they're not involved in boxing, for example. It's useful to bring them up though. – Jon Skeet May 29 '11 at 07:02
  • 1
    @Jon, good point. I suppose they're sometimes considered as primitive wrappers because `AtomicInteger` and `AtomicLong` derive from `Number`, like `Integer` and `Long`. – Frédéric Hamidi May 29 '11 at 07:05
  • Yup. I've gone into this a bit more in my answer - hope you don't mind me taking inspiration from yours :) – Jon Skeet May 29 '11 at 07:08
  • 1
    @Jon, you mean, as opposed to all the times I took inspiration from yours? Please help yourself :) – Frédéric Hamidi May 29 '11 at 07:10
4

Yes, of course. Wrapper classes are immutable.

You can read Why wrapper classes are immutable in java? to understand the immutability of wrapper classes.

0

One odd "wrapper" class is Void which doesn't have any valid objects, immutable or otherwise. It can only be set to null.

One use for Void is to mark generic return types with no value. (You can't use primtive types or void)

e.g.

Callable<Void> callable = new Callable<Void>() {
    public Void call() {
         // do something
        return null;
    }
};

Even though Date is technically mutable, I would describe it as "immutable by convension". It is generally understood or assumed you wouldn't change a Date object but would replace it to change it like any other immutable object.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130