Why would one declare an immutable class final in Java?

Anand picture Anand · Sep 6, 2012 · Viewed 28.4k times · Source

I read that to make a class immutable in Java, we should do the following,

  1. Do not provide any setters
  2. Mark all fields as private
  3. Make the class final

Why is step 3 required? Why should I mark the class final?

Answer

templatetypedef picture templatetypedef · Sep 6, 2012

If you don't mark the class final, it might be possible for me to suddenly make your seemingly immutable class actually mutable. For example, consider this code:

public class Immutable {
     private final int value;

     public Immutable(int value) {
         this.value = value;
     }

     public int getValue() {
         return value;
     }
}

Now, suppose I do the following:

public class Mutable extends Immutable {
     private int realValue;

     public Mutable(int value) {
         super(value);

         realValue = value;
     }

     public int getValue() {
         return realValue;
     }
     public void setValue(int newValue) {
         realValue = newValue;
     }

    public static void main(String[] arg){
        Mutable obj = new Mutable(4);
        Immutable immObj = (Immutable)obj;              
        System.out.println(immObj.getValue());
        obj.setValue(8);
        System.out.println(immObj.getValue());
    }
}

Notice that in my Mutable subclass, I've overridden the behavior of getValue to read a new, mutable field declared in my subclass. As a result, your class, which initially looks immutable, really isn't immutable. I can pass this Mutable object wherever an Immutable object is expected, which could do Very Bad Things to code assuming the object is truly immutable. Marking the base class final prevents this from happening.

Hope this helps!