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).

17 comments:

  1. Hi,

    The above mentioned class is not immutable,

    suppose if we modify the doj object then date object in class1 and class2 also gets modify,
    So care needs to be taken care in constructor when we set the mutable object.

    public final class ImmutableClass {

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

    ReplyDelete
  2. class Immutable {
    private final int value;

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

    public int getValue() {
    return value;
    }
    }

    public class MutableClass extends Immutable {
    private int realValue;
    public MutableClass(int value){
    super(value);
    realValue=value;
    }
    public static void main(String[] args) {
    Immutable immutable = new Immutable(5);
    MutableClass mutable= new MutableClass(10);
    }
    }

    Even if we're not making Immutable class Final , how come above code is changing immutable object value which is 5.
    When MutableClass constructor is being called, it is not affecting Immutable object value.
    Correct me if i'm wrong

    ReplyDelete
    Replies
    1. Hello Mr. Paras,

      Please look into the below given example.

      http://javaexplorer03.blogspot.in/2017/06/why-would-one-declare-immutable-class.html


      Regards

      Delete

Related Posts Plugin for WordPress, Blogger...