Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java immutable-class rules

Is the below class immutable:

final class MyClass {
    private final int[] array;
    public MyClass(int[] array){
        this.array = array;
    }
}
like image 647
JavaUser Avatar asked Jun 29 '10 16:06

JavaUser


People also ask

What is use of immutable class in Java?

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

What is the disadvantage of immutable class in Java?

The only real disadvantage of immutable classes is that they require a separate object for each distinct value. Creating these objects can be costly, especially if they are large.

Can we break immutable class in Java?

More detailed answer: Yes serialization can break immutability. You have to remember that serialization is another way of creating objects (and it is not using constructors).


3 Answers

"Immutability" is a convention between the programmer and himself. That convention may be more or less enforced by the compiler.

Instances of a class are "immutable" if they do not change during the normal course of the application code execution. In some cases we know that they do not change because the code actually forbids it; in other cases, this is just part of how we use the class. For instance, a java.util.Date instance is formally mutable (there is a setTime() method on it) but it is customary to handle it as if it were immutable; this is just an application-wide convention that the Date.setTime() method shall not be called.

As additional notes:

  • Immutability is often thought of in terms of "external characteristics". For instance, Java's String is documented to be immutable (that's what the Javadoc says). But if you look at the source code, you will see that a String instance contains a private field called hash which may change over time: this is a cache for the value returned by hashCode(). We still say that String is immutable because the hash field is an internal optimization which has no effect visible from the outside.
  • With reflection, the most private of instance fields can be modified (including those marked as final), if the programmer wishes so hard enough. Not that it is a good idea: it may break assumptions used by other pieces of code using the said instance. As I said, immutability is a convention: if the programmer wants to fight himself, then he can, but this can have adverse side-effects on productivity...
  • Most Java values are actually references. It is up to you to define whether a referenced object is part of what you consider to be "the instance contents". In your class, you have a field which references an (externally provided) array of integers. If the contents of that array are modified afterwards, would you consider that this breaks immutability of your MyClass instance ? There is no generic answer to that question.
like image 31
Thomas Pornin Avatar answered Oct 06 '22 09:10

Thomas Pornin


No it is not because the elements of the array can still be changed.

int[] v1 = new int[10];
MyClass v2 = new MyClass(v1);
v1[0] = 42;  // mutation visible to MyClass1
like image 79
JaredPar Avatar answered Oct 06 '22 08:10

JaredPar


My two cents regarding immutability rules (which I retained from reading Effective Java - a great book!):

  1. Don't provide methods that can modify the state of an object.
  2. Make all your fields final.
  3. Make sure that your class is non-extendable.
  4. Make all your fields private.
  5. Provide exclusive access to any fields or components of your class that can be changed. Essentially this applies to your situation (as explained by JaredPar). A person that uses your class still has a reference to your array. The opposite is the case where you return a reference to an component of your class. In this case, always create defensive copies. In your case, you should not assign the reference. Instead, copy the array that the user of your class provides, into your internal component.
like image 21
Vivin Paliath Avatar answered Oct 06 '22 09:10

Vivin Paliath