现在的位置: 首页 > 综合 > 正文

Java中shallow clone 与deep Clone的区别

2018年05月24日 ⁄ 综合 ⁄ 共 4678字 ⁄ 字号 评论关闭

Java中实现对象clone的方式是implements Cloneable interface,然后在实现类中重写Object clone()方法.在Java中默认的是"shallow copy", 所以如果类的attribute中含有对象,并且希望实现"deep copy",就要将所涉及的类都 implements Cloneable
and Serializable interfaces, 然后使用对象序列化的方式将对象写入disk, 然后再从disk中读出,并返回. 

In java, There are two different ways that can be used to copy an object:

  1. shallow copy and
  2. deep copy

What is shallow copy in java

  • A shallow copy would copy the object without any of its contents or data, In copied object all the variables are passed by reference from the original object.
  • Remeber that, In shallow copy, Copied object and Original object refer to the same data in memory.
  • Hence modifying the state of the original object would also modify the state of the copied object too.
  • By default, when you call the super.clone() method against an object, It would perform a shallow copy.

shallow copy example in java

/** 
 * Overrides Object's clone method to create a shallow copy 
 * 
 * @return 
 */ 
public Object shallowCopyClone() { 
    try { 
        return super.clone(); 
    } catch (CloneNotSupportedException ex) { 
        return null; 
    } 
}

What is deep copy in java

  • The second type of copy, Deep-copy copies the object including all the contents / states.
  • Hence each object refers to a different space in memory and modifying one object will not affect the other.
  • Remember that to make an exact copy of an object (deep copy), you must serialize the object.

deep copy example in java

/** 
 * Overrides Object's clone method to create a deep copy 
 * 
 * @return 
 */ 
public Object clone() { 
    Object obj = null; 
    try { 
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        ObjectOutputStream oos = new ObjectOutputStream(baos); 
        oos.writeObject(this); 
        oos.close(); 
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
        ObjectInputStream ois = new ObjectInputStream(bais); 
        obj = ois.readObject(); 
        ois.close(); 
    } catch (IOException e) { 
        e.printStackTrace(); 
    } catch (ClassNotFoundException cnfe) { 
        cnfe.printStackTrace(); 
    } 
    return obj; 
}

  • The Object class implements the clone() method And by default, the Object class’s clone() method is protected.
  • To make an object cloneable, you must implement the Cloneable interface and also override the default clone() method.
  • You can make a deep copy of an object by serializing & deserializing it using ByteArrayOutputStream & ByteArrayInputStream classes respectively, Means you need to write the object to an output stream and then
    read it back via an input stream.
  • These steps are shown in the above clone() method.
  • Here the object is written to a ByteArrayOutputStream and then It's read back using a ByteArrayInputStream.
  • Once this occurred, the object has been serialized and that creates the deep copy for any object.
  • So now, In order to make a deep copy of an object, simply just call that object’s overridden clone() method!!

Shallow copy Deep copy in java
A shallow copy would copy the object without any of its contents or data, In copied object all the variables are passed by reference from the original object. Deep copy copies the object including all the contents / states.
In shallow copy, Copied object and Original object refer to the same data in memory. In deep copy, Copied object and Original object refer to the different data in memory having same value / state.
In shallow copy, Modifying the state of the original object would also modify the state of the copied object too. In Deep copy, Modifying the state of the original object would not modify the state of the copied object.
You need to implement Cloneable interface, You can override the  clone() method or you can you super.clone() also. You need to implement Cloneable & Serializable interface, You also have to override the  clone() method to write your deep cloning logic.

import java.util.Date;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.OptionalDataException;
import java.io.Serializable;

public class Monkey implements Cloneable, Serializable {

	private int height;

	private int weight;

	/**
	 * @directed
	 * @clientCardinality 1
	 * @supplierCardinality 1
	 */
	private GoldRingedStaff staff;

	private Date birthDate;

	public Monkey() {
		this.birthDate = new Date();
		this.staff = new GoldRingedStaff();
	}

	public Object deepClone() throws IOException, OptionalDataException,
			ClassNotFoundException {
		//write to stream
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(this);

		//read from stream
		ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
		ObjectInputStream oi = new ObjectInputStream(bi);

		return (oi.readObject());
	}

	public Object clone() {
		Monkey temp = null;
		try {
			temp = (Monkey) super.clone();
		} catch (CloneNotSupportedException e) {
			System.out.println("Clone failed");
		} finally {
			return temp;
		}
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

	public Date getBirthDate() {
		return birthDate;
	}

	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}

	public GoldRingedStaff getStaff() {
		return staff;
	}

}

抱歉!评论已关闭.