Saturday, April 6, 2019

Immutable Class In Java

Q-  What is immutable in java?
Immutable class:-
  • Immutable classes are the classes whose objects value can not be canged once they are initialized.
  • All the wrapper calsse are immutable in java.
  • Immutable objects are instances that can't change the state after it has been initialized
Q-  How to handle mutable reference in immutable class?

Q-  How can we create custom immutable calss in java?
To create the immuatble calss in java we have to follow as given points.
  • Class should be declare final so it can’t be extended.
  • Instance varriable or fields of immutable class should be private final.So that direct access is not allowed. because final is a non-access modifier for Java elements.
  • instance variable "all the fields" should be initialize via the constructer, should be performing deep copy
  • Remove the setter methods (Don’t provide setter methods for variables) so no one can change the value once its initialized.
  • If a immutable calss has mutable reference than make all mutable fields final so that it’s value can be assigned only once.
  • Perform cloning of objects in the getter methods and in constuctor to return a copy rather than returning the actual object reference.
Example:-
package com.shubh.immutable.example;

import java.util.HashMap;
import java.util.Iterator;

public final class MyImmutableClass {

 private final int id;
 private final String name;
 private final HashMap testMap;

 public int getId() {
  return id;
 }

 public String getName() {
  return name;
 }

 public HashMap getTestMap() {
  return testMap;
  // return (HashMap) testMap.clone();
 }

 public MyImmutableClass(int id, String name, HashMap hashMap) {
  System.out.println("Performing Deep Copy for Object initialization");
  this.id = id;
  this.name = name;

  HashMap tempMap = new HashMap();
  String key;
  Iterator it = hashMap.keySet().iterator();
  while (it.hasNext()) {
   key = it.next();
   tempMap.put(key, hashMap.get(key));
  }
  this.testMap = tempMap;
 }

 public static void main(String[] args) {

  int id = 10;
  String name = "My First Company";
  HashMap map = new HashMap();
  map.put("1", "String One");
  map.put("2", "String Two");

  // Create instance of MyImmutableClass calss
  MyImmutableClass myImmObj = new MyImmutableClass(id, name, map);

  System.out.println("1)  Id: " + myImmObj.getId() + ", Name: "+ myImmObj.getName() + ", TestMap: " + myImmObj.getTestMap());
  System.out.println(" ");
  System.out.println("##### Now lets change values of local variable");
  id = 20;
  name = "My Second Company";
  map.put("3", "String Three");

  // After Change lets print the values again
  System.out.println("2) After Change ###### Id:" + myImmObj.getId()+ ", Name: " + myImmObj.getName() + ", TestMap: "+ myImmObj.getTestMap());

  HashMap hmTest = myImmObj.getTestMap();
  hmTest.put("4", "New String");
  System.out.println(" ");
  System.out.println("3) Check testMap after changing variable from accessor methods: " + myImmObj.getTestMap());
 }
}

 
Q-  How to identify that object is immutable object in java?
  • Check if every field is private final.
  • Check if class is final.
  • Check for mutable members.
Question : What is output of below program? can we change the value of object ?
package com.javaiq.in.user;

public class MainFinalReferenceTest {

	public static void main(String[] args) throws ClassNotFoundException, CloneNotSupportedException {
		// get the Class instance using new Operator
		final User ref = new User();
		ref.setId(1);
		ref.setName("User1");
		System.out.println(ref.toString());
	}
}
Yes, we can change the value of object, here only reference is final. So we can not assign new object into same reference.
package com.javaiq.in.user;

public class MainFinalReferenceTest {

	public static void main(String[] args) throws ClassNotFoundException, CloneNotSupportedException {
		// get the Class instance using new Operator
		final User ref = new User();
		ref.setId(1);
		ref.setName("User1");
		System.out.println(ref.toString());

		// set new values
		ref.setId(2);
		ref.setName("User2");
		System.out.println("Changed Value : " + ref.toString());
	}
}

Output:

User [id=1, name=User1]
Changed Value : User [id=2, name=User2]

No comments:

Post a Comment