Showing posts with label Immutability. Show all posts
Showing posts with label Immutability. Show all posts

Friday, 9 June 2017

Why would one declare an immutable class final in Java?


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

Example:
package com.dp;
class Immutable {
     private final int value;

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

     public int getValue() {
           return value;
     }
}

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);
           /**
            * Object obj is Mutable object which seem like Immutable
            * as it has been caste into the parent class.
            */
           Immutable immObj = (Immutable)obj;

           System.out.println(immObj.getValue());
           /**
            * Changing the state on Mutable class which is
            * referenced by the immutable class.
            */
           obj.setValue(8);

           /**
            * It will print the mutable class value field as immObj  
            * contains the instance of the Mutable class.
            */
           System.out.println(immObj.getValue());
     }
}

Notice, In the Mutable subclass, we've overridden the behavior of getValue to read a new, mutable field declared in my Mutable subclass. As a result, our object, which initially looks immutable, really isn't immutable (contains the instance of the mutable class).

In above scenario, we have passed Mutable object wherever an Immutable object is expected, which can lead a big trouble while execution of code because we are assuming the object is truly immutable(Problem when this object will use the key of HashMap).


Marking the base class final prevents this from happening.

Thursday, 4 May 2017

Minimize mutability or Create an immutable class

An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.

JDK immutable classes: String, the boxed primitive classes(wrapper classes), BigInteger and BigDecimal etc.

How to make a class immutable?

1. Don’t provide any methods that modify the object’s state (known as mutators).
2. Ensure that the class can’t be extended.
3. Make all fields final.
4. Make all fields private.
This prevents clients from obtaining access to mutable objects referred to by fields and modifying these objects directly.
5. Make defensive copies.
Ensure exclusive access to any mutable components.


public List getList() {
     return Collections.unmodifiableList(list); <=== defensive copy of the mutable
                                                                              field before returning it to the caller
}

If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object reference or return the object reference from an accessor.

import java.util.Date;
public final class ImmutableClass {

       public ImmutableClass(int id, String name, Date doj) {
              this.id = id;
              this.name = name;
              this.doj = new Date(doj.getTime());
       }

       private final int id;
       private final String name;
       private final Date doj;

       public int getId() {
              return id;
       }
       public String getName() {
              return name;
       }

     /**
      * Date class is mutable so we need a little care here.
      * We should not return the reference of original instance variable.
      * Instead of a new Date object, with content copied to it, should be returned.
      * */
       public Date getDoj() {
              return new Date(doj.getTime()); // For mutable fields
       }
}
import java.util.Date;
public class TestImmutable {
       public static void main(String[] args) {
              String name = "raj";
              int id = 1;
              Date doj = new Date();
             
              ImmutableClass class1 = new ImmutableClass(idnamedoj);
              ImmutableClass class2 = new ImmutableClass(idnamedoj);
      // every time will get a new reference for same object. Modification in              reference will not affect the immutability because it is temporary reference.
              Date date = class1.getDoj();
              date.setTime(date.getTime()+122435);
              System.out.println(class1.getDoj()==class2.getDoj());
       }
}

Ensure that the class can’t be extended?
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;
     }
}

Why Immutability?
1. They are less prone to error and are more secure.

2. Immutable classes are easier to design, implement, and use than mutable classes.

3. Immutable objects are thread-safe so there are no synchronization issues.

4. Immutable objects are good Map keys and Set elements since these typically do not change once created.

5. Immutability makes it easier to write, use and reason about the code (class invariant is established once and then unchanged).

6. Immutability makes it easier to parallelize program as there are no conflicts among objects.

7. The internal state of the program will be consistent even if you have exceptions.

8. References to immutable objects can be cached as they are not going to change.(i.e in Hashing it provide fast operations).
Related Posts Plugin for WordPress, Blogger...