Showing posts with label Clone(). Show all posts
Showing posts with label Clone(). Show all posts

Using Mutable Objects inside user defined Immutable Class

We may aware of creating user defined Immutable Class in Java. Basic steps to follow to create immutable class are
Using Mutable Objects inside user defined Immutable Class

  • Maintain all member variables and class has defined with final keyword so that variables value can't be modifies and class can't be overridden. 
  • Variables values must to set through constructor or through factory pattern.
  • Provide only getter methods for member variable. 
In below example lets see simple code which uses mutable object as member variable inside our Immutable class. By returning same original Object in getter which gives loop for user to alter the Objects internal values.


public class Employee {
 private int id;
 private String name;
 private int age;
 
 public Employee(int id, String name, int age) {
  this.age = age;
  this.id = id;
  this.name = name;
 }

 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 } 
}



public final class MyImmutableClass {

 private final int count;
 private final Employee obj;
 
 public MyImmutableClass(int count, Employee obj) {
  this.count = count;
  this.obj = obj;
 }
 public int getCount() {
  return count;
 }
 public Employee getObj() {
  return obj;
 } 
}



public class MyTestClass {

 public static void main(String[] args) {
  
  MyImmutableClass obj1 = new MyImmutableClass(1, new Employee(100, "Steve", 51));
  
  // Here we have created Immutable object for "MyImmutableClass" class
  // Lets see how to change values of mutable object inside Immutable object
  
  obj1.getObj().setName("James");
  
  System.out.println("Count    : "+obj1.getCount());
  System.out.println("Emp ID   : "+obj1.getObj().getId());
  System.out.println("Emp Name : "+obj1.getObj().getName());
  System.out.println("Emp Age  : "+obj1.getObj().getAge());
  
 }
}


OUTPUT:


Count    : 1
Emp ID   : 100
Emp Name : James
Emp Age  : 51


In above example we can see mutable object inside immutable class getting changed. We have created Immutable object with employee name as "Steve" but later same immutable objects value getting changed from "Steve" to "James".
Next we will see how to avoid changing mutable object in Immutable class. For this we need to change 2 things in our above classes 
  • In Employee class implements Cloneable and override clone method.
  • Next in MyImmutableClass class we need to return clone object instead of original Employee Object. 
Below are the class code changed. 


public class Employee implements Cloneable{
 private int id;
 private String name;
 private int age;
 
 public Employee(int id, String name, int age) {
  this.age = age;
  this.id = id;
  this.name = name;
 }

 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 } 
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}



public final class MyImmutableClass {

 private final int count;
 private final Employee obj;
 
 public MyImmutableClass(int count, Employee obj) {
  this.count = count;
  this.obj = obj;
 }
 public int getCount() {
  return count;
 }
 public Employee getObj() {
  try {
   return (Employee)obj.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return null;
 } 
}


Next run same code MyTestClass class.

OUTPUT:


Count    : 1
Emp ID   : 100
Emp Name : Steve
Emp Age  : 51


Here we can see even we have changed Employee name from "Steve" to "James" actual object not getting disturbed. 



Deep Copy in Java


Deep Copy in Java
In our earlier tutorial we have seen about Shallow copy and how we can implement and how its works in Java. Same way we will see about Deep copy in this tutorial.

Deep copy - by name itself we can identify as its copy complete Object in-depth while cloning any instance. In Shallow copy we have seen that Object which holds another Object will not be copied and only holds the address reference. Where as in Deep copy it copies those Objects also and creates the instance for those Objects. Apart from this difference Deep copy is same as Shallow copy like, explicitly we need to type cast to our class and Constructors will not be called in our cloning class, but Object which contains other Object class constructors will be called while cloning from clone() method instance creation. 


We will see same example which we have seen in Shallow copy and make changes only in our clone() method to implement Deep Copy.


public class Subject{
 
 String name;
 
 public Subject(){
  System.out.println("Inside Default Constructor");
 }
 
 public Subject(String name){
  System.out.println("\nInside Constructor");
  this.name = name;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 } 
}



public class Student implements Cloneable{

 String name;
 Subject sub;
 
 public Student(String name, String sub){
  this.name = name;
  this.sub = new Subject(sub);
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Subject getSub() {
  return sub;
 }
 public void setSub(Subject sub) {
  this.sub = sub;
 } 
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return new Student(name, sub.getName());
 }
}



public class DeepCopy {

 public static void main(String[] args) throws CloneNotSupportedException {
  
  Student stu = new Student("Raj", "Hindi");
  
  System.out.println("\nOriginal Student Name: "+stu.getName());
  System.out.println("Original Student Sub : "+stu.getSub().getName());
  
  // Cloning the original Object and Explicitly type casting 
  Student stu1 = (Student)stu.clone();
  
  System.out.println("\nClone Student Name: "+stu1.getName());
  System.out.println("Clone Student Sub : "+stu1.getSub().getName());
  
  stu1.setName("David");
  
  
  /*
   * In Deep copy cloned Object will hold complete copy of original Object
   */
  stu1.getSub().setName("Tamil");
  
  System.out.println("\nOriginal Student Name: "+stu.getName());
  System.out.println("Original Student Sub : "+stu.getSub().getName());
  
  System.out.println("\nClone Student Name: "+stu1.getName());
  System.out.println("Clone Student Sub : "+stu1.getSub().getName());
 }
}


OUTPUT:


Inside Constructor

Original Student Name: Raj
Original Student Sub : Hindi

Inside Constructor

Clone Student Name: Raj
Clone Student Sub : Hindi

Original Student Name: Raj
Original Student Sub : Hindi

Clone Student Name: David
Clone Student Sub : Tamil



In above output we can see Subject name ("Tamil") has changed only for the cloned Object, where as in Shallow copy it holds the address of Object. 
    




Shallow copy in Java


Shallow copy in Java


In one of our earlier tutorial we have seen about Java clone. In this tutorial we will see about Shallow Copy with simple example code. Also we will about What is Shallow Copy and how its works. Before we knowing about Shallow Copy or Shallow Clone we need to know about what is clone and how its working in Java upon Objects.

As already we have seen in our previous tutorial Clone is nothing but the process of copying one Object to produce the exact copy, but not guaranteed for all Objects can be cloned. Suppose if the Object is not supported for cloning then we can't make another copy, in that case we will get CloneNotSupportedException Exception. If the class is Fully singleton class and as per rule we can't make another copy of the class, hence it will be a best example for clone not allowed. Cloning can be divided into two types as 

  • Shallow Copy 
  • Deep Copy

In this tutorial we will see about only Shallow copy with simple example code and how its working. Shallow copy is nothing but default clone implementation where it create new instance and copy all the field of object to the new instance and returns the Object type.  Object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, it holds just the address reference of the other Objects rather copying complete instance is called Shallow copy. 

Explicitly we need to type cast to our class as given in below example. Basically if a class need to support cloning then we need to implement Cloneable interface and need to Override clone method also. 

Now all we know that clone will be Shallow or Deep copy to create a new copy of the class object. Here interviewer will interrupt and put a question like when we clone object whether Class constructor will be called or not? Suddenly our ears will open widely and start thinking. Answer will be NO, while cloning any class object constructor will not be called. 

Lets see simple example for Shallow copy and how its works.


public class Subject{
 
 String name;
 
 public Subject(){
  System.out.println("Inside Default Constructor");
 }
 
 public Subject(String name){
  System.out.println("Inside Constructor");
  this.name = name;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 } 
}



public class Student implements Cloneable{

 String name;
 Subject sub;
 
 public Student(String name, String sub){
  this.name = name;
  this.sub = new Subject(sub);
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Subject getSub() {
  return sub;
 }
 public void setSub(Subject sub) {
  this.sub = sub;
 } 
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}



public class ShallowCopy {

 public static void main(String[] args) throws CloneNotSupportedException {
  
  Student stu = new Student("Raj", "Hindi");
  
  System.out.println("\nOriginal Student Name: "+stu.getName());
  System.out.println("Original Student Sub : "+stu.getSub().getName());
  
  // Cloning the original Object and Explicitly type casting 
  Student stu1 = (Student)stu.clone();
  
  System.out.println("\nClone Student Name: "+stu1.getName());
  System.out.println("Clone Student Sub : "+stu1.getSub().getName());
  
  stu1.setName("David");
  
  
  /*
   * In shallow Object contains other Objects which will have only
   * the address reference. Hence by below line Language will change 
   * in both the Objects (Original as well as in Cloned)
   */
  stu1.getSub().setName("Tamil");
  
  System.out.println("\nOriginal Student Name: "+stu.getName());
  System.out.println("Original Student Sub : "+stu.getSub().getName());
  
  System.out.println("\nClone Student Name: "+stu1.getName());
  System.out.println("Clone Student Sub : "+stu1.getSub().getName());
 }
}


OUTPUT:


Inside Constructor

Original Student Name: Raj
Original Student Sub : Hindi

Clone Student Name: Raj
Clone Student Sub : Hindi

Original Student Name: Raj
Original Student Sub : Tamil

Clone Student Name: David
Clone Student Sub : Tamil



In above output we can see Subject ("Tamil") has changed for both the Objects, original as well as Cloned Object as we have changed Subject Name only for cloned Object in our code. 
Its the example for Shallow copy where Object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, it holds just the address reference of the other Objects rather copying complete instance into cloned instance. 






Java Clone()



In this tutorial we will see about Java Clone and how to implement in our coding. Before jumping into coding lets discuss What is Java Clone and how its working.

What is Java Clone?
Clone is nothing but creating a copy of Object with the same state of cloning Object. For example if we clone a Object called "obj1" to "obj2" then new Object will be created with same state and value. There are Shallow copy and Deep copy which we will discuss in our next tutorial.

How its Working?
Suppose if we need to use clone for our class then we need to implement Cloneable interface in our class with clone() method, which will create a copy of super class and return's the Object. Below example will gives you how to use use clone() on user defined class and Collection Objects.



public class MyClass implements Cloneable {

 String name;
 String company;

 public MyClass(String name, String company) {
  System.out.println("Inside Constructor....");
  this.name = name;
  this.company = company;
 }

 public String getName() {
  return this.name;
 }

 public String getCompany() {
  return this.company;
 }

 public Object clone() {
  try {
   MyClass cloned = (MyClass) super.clone();
   return cloned;
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
   return null;
  }
 }
}




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

  MyClass obj1 = new MyClass("Kamal", "ABC Limited.");

  System.out.println("\nName    : " + obj1.getName());
  System.out.println("Company : " + obj1.getCompany());

  // Cloning the Object
  MyClass obj2 = (MyClass) obj1.clone();

  System.out.println("\nName    : " + obj2.getName());
  System.out.println("Company : " + obj2.getCompany());

  ArrayList<String> arr1 = new ArrayList<String>();
  arr1.add("Java");
  arr1.add("J2EE");
  System.out.println("\nFirst ArrayList  : "+arr1);
  
  ArrayList<String> arr2 = (ArrayList<String>) arr1.clone();
  System.out.println("\nSecond ArrayList : "+arr2);
 }
}



OUTPUT:


Inside Constructor....

Name    : Kamal
Company : ABC Limited.

Name    : Kamal
Company : ABC Limited.

First ArrayList  : [Java, J2EE]

Second ArrayList : [Java, J2EE]