How to create Immutable Class In Java

         How to create Immutable Class In Java


Hi all, its been a long time . Was really busy with work :).Got some time now to learn new things again .Today I am going to explain you all how to create immutable class in java.First of all what is immutable ? Immutable means can't be changed once created. 

Immutable Class:

Immutable classes are the one which cant be extended by any other sub class and should not able to change the value of any mutable and immutable variable inside the class, should not allow the methods to get override.


Properties of Immutable Class:


Let me tell you the properties an immutable class should hold.

  • Class should be final 
  • All the variable inside the class should be  private final 
  • All the method should be final 
  • Don't create any setter methods 
  • Create a constructor to initialize all the variables
  • Provide a public get method for all the variables, for mutable object clone and return the copy  of the  object .
e.g Collections -List,Map and Date fields are mutable. Immutable objects like String will always return the new String for any modifications so it wont affect the original object say for example if you are trying to concat some thing with the string field,you need to assign the same to the variable again to see the modified string but since you are making it as final variable you cant assign the string second time or other than constructor .
  • While cloning object always prefer deep cloning where both object and contained objects also copied . And get method of mutable variable should always do the same 



 I am going to show the example program which explains the above.

package com.immutableclass.test;

import java.util.HashMap;
import java.util.Map;

public final class ImmutableTest implements Cloneable {

private final String name;
private final int count;
private final Map<String, String> testmap;

public String getName() {
return name;
}

public int getCount() {
return count;
}

@SuppressWarnings("unchecked")
public Map<String,String> getTestmap()
throws CloneNotSupportedException {
Map<String,String>testmapCopy= new HashMap<String, String>();
for (Map.Entry<String, String> map : this.testmap.entrySet()) {
testmapCopy.put(map.getKey(), map.getValue());
}
return testmapCopy;

}

 

public ImmutableTest(String name, int count, Map<String, String> testMap) {
super();
this.name = name;
this.count = count;
// this.testmap=testMap;//shallow copy refers the same map so any change will affect the source
this.testmap = new HashMap<String, String>();// deep copy create new object and set the value so changes wont affect the source
for (Map.Entry<String, String> map : testMap.entrySet()) {
testmap.put(map.getKey(), map.getValue());
}
}

public static void main(String[] args) throws CloneNotSupportedException {
Map<String, String> testmap = new HashMap<String, String>();
testmap.put("1", "sa");
testmap.put("2", "ra");
String name="original";
int count=0;
ImmutableTest immutableTest = new ImmutableTest(name,count, testmap);
System.out.println(immutableTest.getName());
System.out.println(immutableTest.getCount());
System.out.println(immutableTest.getTestmap());
System.out.println("concat string with original- "+immutableTest.getName()
               .concat(" modified"));//concat will retrun new string all the string functions inside 
                string class returns new string
System.out.println("after concatination str with original- "+name);
name="modified";
System.out.println("local variable name changed -"+name);
count=count++;
System.out.println("local variable count changed- "+count);
System.out.println("original count- "+immutableTest.getCount());
System.out.println("original name- "+immutableTest.getName());
Map<String,String> map1=immutableTest.getTestmap();
map1.remove("2");
System.out.println("map changed -"+map1);
System.out.println("original map -"+immutableTest.getTestmap());
map1= new HashMap<String, String>();
System.out.println("local map intialization again- "+map1);
}

}

Output


original
0
{2=ra, 1=sa}
concat string with original- original modified
after concatination str with original- original
local variable name changed -modified
local variable count changed- 0
original count- 0
original name- original
map changed -{1=sa}
original map -{2=ra, 1=sa}
local map initialization again- {}


To check the how deep copy or shallow copy works in immutable class  change the get method of testmap and constructor as below

public Map<String, String> getTestmap() {
return testmap;
}

Constructor with shallow copy
public ImmutableTest(String name, int count, Map<String, String> testMap) {
super();
this.name = name;
this.count = count;
this.testmap=testMap;
}

Comments

Popular posts from this blog

Get rid of boring for loop and try using "range" and "rangeClosed"

Custom Exception Handling For Spring Boot Rest Controller

HOW TO USE NOTE PAD AS YOUR PERSONAL DAIRY!!!!!