Namek Dev
a developer's log
NamekDev

Immutability of Java's Integer

July 6, 2012

As Wiki states

In object-oriented […], an immutable object is an object whose state cannot be modified after it is created.

That totally applies to Java’s Integer. Let’s take a look at the code to talk about:

Integer a = 5;
Integer b = a;
b = b+1;
System.out.println("a = " + a);  // a = 5
System.out.println("b = " + b);  // b = 6

Integer is a class then why variables a and b have different values?! - you may ask. See the explanation if eager.

Fast explanation

Integer is an object so the references should work here. They should. But Java language designers liked it to be rather immutable.

When some object is immutable it means that it’s state (you may say - value) is fixed. Getting straight to the point - look at the code above and read: because of immutability variable b cannot reference to the object a, so a and b are different objects and so on - b’s value isn’t a’s value.

Integer’s increment - how?

Let’s ask. So if variable a can’t be changed then how does work the following?

Integer a = 1000;
a++;
System.out.println("a = " + a);  // a = 1001

It will compile because it is implemented to allow such a shortcut. Look at the real code behind:

Integer a = new Integer(1000);
a = new Integer(a.intValue() + 1);
System.out.println("a = " + a.toString());  // a = 1001

So you see that notation above of above is just a shortcut which is implemented in the compiler of course.

Define mutable Integer

If you’d like to use Integer with a reference manner (store that reference and change value of the same object) then you have to define your own MutableInteger.

This is how to use MutableInteger:

MutableInteger a = new MutableInteger(1000);
a.setValue(1001);
System.out.println("a = " + a);  //toString() method is being used

Integer b = a.intValue(); // copying value. Changing 'b' won't change 'a'

And this is the class:

public class MutableInteger extends Number
    implements Comparable<MutableInteger>
{
    protected int integer;

    // Constructors
    public MutableInteger(int v)
    {
        integer = v;
    }

    public MutableInteger(double v)
    {
        integer = (int)v;
    }

    public MutableInteger(float v)
    {
        integer = (int)v;
    }

    public MutableInteger(byte v)
    {
        integer = (int)v;
    }

    public MutableInteger(long v)
    {
        integer = (int)v;
    }

    // Conversions to other values
    @Override
    public double doubleValue()
    {
        return (double)integer;
    }

    @Override
    public float floatValue()
    {
        return (float)integer;
    }

    @Override
    public int intValue()
    {
        return integer;
    }

    @Override
    public long longValue()
    {
        return (long)integer;
    }

    public byte byteValue()
    {
        return (byte)integer;
    }

    // Changing the value
    public void setValue(int v)
    {
        integer = v;
    }

    public void setValue(long v)
    {
        integer = (int)v;
    }

    public void setValue(byte v)
    {
        integer = (int)v;
    }

    public void setValue(float v)
    {
        integer = (int)v;
    }

    public void setValue(double v)
    {
        integer = (int)v;
    }

    // Object.toString() override (conversion to String)
    @Override
    public String toString()
    {
        return Integer.toString(integer);
    }

    // Comparable<MutableInteger> implementation
    @Override
    public int compareTo(MutableInteger other)
    {
        return this.integer - other.integer;
    }
}

Note: MutableInteger encapsulates Integer here so there can bee seen a Wrapper design pattern.

MutableInteger in practice

Such MutableInteger can be seen sometimes in various projects, but to my experience a need for that is very low due to data being sent between objects. It’s really rare to store reference to only integer. Mostly there is more information - like: position, speed or radius/strength of a Bullet (for example).

It’s rather simple to write MutableInteger class. The disadvantage when use is that you can’t change it’s value like of normal integer’s. It’s because of lack of redefined equal operator (=). But on the other side it is an advantage because we won’t lose our object due to some mistake by using object with equal operator or so.

comments powered by Disqus