Wednesday 26 June 2013

What is Defensive Copying , Shallow Copy and Deep Copy ?


Defensive copying is concerned with protecting mutable objects e.g. objects who’s state can be modified by the user. If you were pass back the reference of an object any changes a user made to that copy of the object would effect your object because you are only passes a reference to the object and not the actual object itself. This is known as a shallow copy.

To avoid users being able to change the values of your object you can pass back a defensive copy. This means that instead of passing back a reference to your object it passes back a new object but with the same values. This means that any changes the user makes to that copy of the object doesn’t change the value/state of your object.

It’s an interesting idea but I can’t think of a use for this at the moment but I’m sure one day this will come in useful.

Before knowing about Shallow Copy and Deep Copy you need to know about Clonable interface.

Clonable interface - 
    Java has a clonable interface for make clone of any object.
    Clonable Interface is a marker interface. 
    Clonable Interface has no method.
    Class which implements Clonable interface, JVM give the permission for making the clone of         this class.

Shallow Copy -         
    Clone can be archived by object.clone() method. It gives the Shallow copy of the object. In this process a new object is created That have all the value and instance variable. And if main object has any references to other object then the references are copied in the shallow copy.

Example - 

class A implements Cloneable{
    
    A(String personName, Integer age){
        this.personName=personName;
        this.age=age;
    }
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    private String personName = null;
    private transient Integer age = null;
    
    public Integer getAge() {
        return age;
    }
    public String getPersonName() {
        return personName;
    }
}

public class Test{
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A("Albar", new Integer(50));
        A a1 = (A)a.clone();
        System.out.println(a1.getPersonName());
    }
}

Deep Copy:- 
    Deep Copy of any object can be achieved by write the object into byte stream and again deserialize it. It gives the Deep Copy of the object. Deep copy is a totally duplicate copy of an object. 
And if main object has any references to other object then the complete new copies of those objects will be available  in the Deep Copy.


Example to get Deep Copy - 

class A implements Serializable{
    
    A(String personName, Integer age){
        this.personName=personName;
        this.age=age;
    }
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    private String personName = null;
    private transient Integer age = null;
    
    public Integer getAge() {
        return age;
    }
    public String getPersonName() {
        return personName;
    }
}


public class Test{
    public static void main(String[] args) throws CloneNotSupportedException {
        try {
            A a = new A("Albar", new Integer(50));
            A deepCopy = null;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            ObjectOutputStream out = new ObjectOutputStream(bos);

            out.writeObject(a);
            out.flush();
            out.close();

            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            Object obj = in.readObject();
            deepCopy = (A)obj;
            System.out.println(deepCopy.getPersonName());
            }
            catch(IOException e) {
                e.printStackTrace();
            }
            catch(ClassNotFoundException cnfe) {
                cnfe.printStackTrace();
            }
            } 
}

http://www.javapractices.com/Topic15.cjp
http://en.wikipedia.org/wiki/Defensive_copy