Wednesday, December 18, 2013

How to make a java class immutable

Most of us know about mutable and  immutable concept and advantages of immutable class in java.
But many of those think we can not make our own java class as immutable  and it is by pre defined. It is not true, we can make our own classes as immutable.
Any way as we discussing immutability concept I want to discuss the advantages of  immutability concept here.

Benefits 
Immutable classes
  1. Are automatically thread-safe and have no synchronization issues
  2. Do not need a copy constructor
  3. Do not need an implementation of clone
  4. Allow hashcode to use lazy initialization, and to cache its return value
  5. Do not need to be copied defensively when used as a field
  6. Make good Map keys  and set elements (these objects must not change state while in the collection)
Making Class as Immutable 
Java Documentation as itself some notes on this concept you can find that here  

1) Don’t provide “setter” methods  
Setter methods are meant to change the state of object and this is what we want to prevent here.
2) Make all fields final and private 
Fields declared private will not be accessible outside the class and making them final will ensure the even accidentally you can not change them
3) Declare class as final
 Don’t allow subclasses to override methods
4) Attention with mutable instance variables in class
Always remember that you can have either mutable  or immutable instance variables, identify them and return new objects with copied content for all mutable objects. Immutable variables can be returned safely without extra effort.

Example :


public final class Employee{

/**
* Integer class is immutable
* */
private final Integer id;

/**
* String class is immutable 
* */
private final String name;

/**
* Date class is mutable 
* */
private final Date dob;

public Employee(Integer id, String name, Date dob)
{
     this.id = id;
     this.name = name;
     this.dob = new Date(dob.getTime());
}

//Provide no setter methods

/**
* Integer class is immutable so we can return the instance variable as it is
* */
public Integer getId() {
        return id;
}

/**
* String class is also immutable so we can return the instance variable as it is
* */
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 a new Date object, with content copied to it, should be returned.
* */
public Date getDob() {
         return new Date(dob.getTime());
}

@Override
public String toString() {
      return id +" - "+ name +" - "+ dob;
}
}


Main Class


public class ImmutableTest
{
     public static void main(String[] args)
     {
           Employee e = new Employee(100,"ABC", new Date());
           System.out.println(e);
           modifyEmployee(e);
           System.out.println(e);
      }

      private static void modifyEmployee(Employee e)
     {
            Integer id = e.getId();
            id = 1000;
           String name = e.getName();
           name = "XYZ";
           Date dob = e.getDob();
           dob.setDate(12);
     }
}


OUT PUT

100 - ABC - Wed Dec 18 17:15:08 IST 2013
100 - ABC - Wed Dec 18 17:15:08 IST 2013

Please let us know of your comments.


1 comment:

Distributed Transactions

What is a distributed transaction?  Transactions that span over multiple physical systems or computers over the network, are simply termed D...