Primitive wrapper types are immutable

You know what I'm talking about, don't you? In Java everything is an object, with the notable exception of a few primitive types (like int, float, ...). But since (almost) everything in Java is an object, all the generic functionality are not designed to work on primitive values. For this reason there are wrapper types (like Integer) that do what expected, that is, wrapping a primitive value in a object.

There is just a detail that we have to keep in mind: wrappers are immutable. This does not mean that we can't apply, for instance, the operator ++ to an Integer, just that it won't increase the existing object value, but create a new Integer with the increased value.

This fact has an interesting consequence in conjunction to the rule that Java passes parameters to function by value.

We know that if I have such a method:
private void increase(int aValue) {
    System.out.println("Value increased to " + ++aValue);
}
This increase() method works on a copy of the passed value so we won't have any side effect on the caller:
int seven = 7;
increase(seven);
System.out.println("Seven is still " + seven);
If we want to have a side effect, we should play with the fact that when we pass in Java an object to a method we actually pass a copy of the pointer to the object, and not of the complete object itself.

So, to simulate a passing by reference in Java, we should wrap our value in an object. A first way of doing that could be putting our primitive value in an array:
private void increase(int arr[]) {
    System.out.println("Value increased to " + ++arr[0]);
}

void f() {
    // ...
    int[] arr = new int[1];
    arr[0] = 7;
    increase(arr);
    System.out.println("It was seven, now it is " + arr[0]);
    // ...
}
Alternatively, we could think about creating a wrapper class:
class Wrapper {
    int value;

    public Wrapper(int value) {
        this.value = value;
    }
}
Rewriting the increase() method:
private void increase(Wrapper w) {
    System.out.println("Value increased to " + ++w.value);
}
We could write the call code:
Wrapper w = new Wrapper(7);
increase(w);
System.out.println("It was seven, now it is " + w.value);
You could think that makes no sense using a custom wrapper when we have the standard ones. But here is the caveat: Integer is immutable, we can't actually change the wrapped value. If we try to use a method like this one:
private void increase(Integer i) {
    System.out.println("Value increased to " + ++i); // no, no, no!
}
We won't get what we could have expected:
// wrapper types are immutable!
Integer i = new Integer(7);
increase(i);
System.out.println("The value is still " + i);
A better solution than creating our own wrapper is using the lang.mutable.* classes provided by the Apache Commons Lang library.

2 comments: