Immutability of Java's Integer
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.