Customized Immutable Class

Java Immutable Class

In Java, when we create an object of an immutable class, we cannot change its value. For example, String is an immutable class. Hence, we cannot change the content of a string once created.

Besides, we can also create our own custom immutable classes. Here's what we need to do to create an immutable class.

  • declare the class as final so it cannot be extended
  • all class members should be private so they cannot be accessed outside of class
  • shouldn't contain any setter methods to change the value of class members
  • the getter method should return the copy of class members
  • class members are only initialized using constructor.
PROS - Immutable Object is Threadsafe. For Constant Value. Used as a HashMap Key. (String, Integer, all wrapper classes are immutable)

Why Hashmap key should be immutable?
Immutability allows you to get same hash code every time, for a key object. So it actually solves most of the problems in one go. Also, this class must honor the hashCode() and equals() methods contract.

// class is declared final
final class Immutable {

  // private class members
  private String name;
  private int date;

  Immutable(String name, int date) {

    // class members are initialized using constructor
    this.name = name;
    this.date = date;
  }

  // getter method returns the copy of class members
  public String getName() {
    return name;
  }

  public int getDate() {
    return date;
  }

}

class Main {
  public static void main(String[] args) {

    // create object of Immutable
    Immutable obj = new Immutable("Prashant", 2011);

    System.out.println("Name: " + obj.getName());
    System.out.println("Date: " + obj.getDate());
  }
}

Output :

Name: Prashant
Date: 2011

Case 2 When a Immutable class contains a mutable reference

Suppose a Employee Immutable class contains a Address mutable reference.

We can get the address and can change it.


We will return the new object of Address every time so that the original object will not change.

Case 3 What if we want to add a new variable in the Address class then we have to modify the getAddress again. This is not a good solution.

To handle this we will use copy constructor.







Reflection can break the Immutability - How we can prevent it?

To prevent it, we can take help of SecurityManager, define this method in ReflectionTest and uncomment its calling. This method prevents access check on private fields / methods via reflection.

private static void setSecuritymanager() { 
 
    System.setSecurityManager(new SecurityManager() { 
        @Override 
        public void checkPermission(Permission perm) { 
             if (perm.getClass() == ReflectPermission.class && "suppressAccessChecks".equals(perm.getName())) { 
                throw new SecurityException("can't supress AccessChecks"); 
            } 
        } 
    }); 
Now line nameField.setAccessible(true); throws exception.


Comments

Popular posts from this blog

Java 8 : Find the number starts with 1 from a list of integers

Optional Vs Null Check

How to prevent Singleton Class from Reflection and Serialization