【Java】3-淺拷貝/ 2-深拷貝

TypantK發表於2019-03-21

三種淺拷貝

  • 構造器:ArrayList newArray = new ArrayList(oldArray);

底層呼叫Arrays.copyOf()和System.arraycopy()完成拷貝

這裡的System.arraycopy()可以等價於陣列的Clone(),也是淺拷貝

 

  • Clone():ArrayList newArray = (ArrayList<E>)oldArray.clone();

ArrayList實現了Cloneable介面,呼叫Object的Clone() --> Object的Clone()是淺拷貝

對於elementData的操作只是讓兩個ArrayList不共享同一個elementData(因為elementData是陣列也就是引用型別)

Arrays.copyOf()底層還是System.arraycopy(),淺拷貝

 

  • 集合方法(等同於一般物件的setter方法,使用=符號):newArray.add(e);

ArrayList<E> newArray = new ArrayList<E>();
    for(E e : oldArray){
        newArray.add(e);
    }

底層也是呼叫System.arraycopy,所以也是淺拷貝,沒有對陣列裡面的物件做處理

 

  • 集合方法:newArray.addAll(oldArray);

ArrayList<E> newArray= new ArrayList<E>();
newArray.addAll(oldArray);

也用到了System.arraycopy,效果等同於陣列物件的Clone(),淺拷貝

 

 

深拷貝

對需要拷貝物件內的物件實現Serializable介面,通過位元組流拷貝

class Person implements Serializable{
	String name;
	int age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "姓名:"+this.name+"-年齡:"+this.age;
	}
}
public void deepCopy(ArrayList<Person> oldArray)throws Exception{

    	ByteArrayOutputStream baos = new ByteArrayOutputStream();

    	ObjectOutputStream oos = new ObjectOutputStream(baos);

    	oos.writeObject(oldArray);

    	ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

    	ObjectInputStream ois = new ObjectInputStream(bais);

    	ArrayList<Person> newArray = (ArrayList<Person>)ois.readObject();

}

 

重寫Clone()方法

這個比較好理解,因為Clone()方法對於當前呼叫物件這一層(父層)是深拷貝,只是對呼叫物件內的子物件(子層)是淺拷貝

也就是說,我們重寫父層類的Clone()方法,讓其對子層也進行Clone()就可以達到深拷貝的效果

(如果還需要拷貝子物件的孫物件,還需要重寫子層的Clone()方法)

*注意:重寫和呼叫Clone()都要實現Clonable介面,不然會報CloneNotSupportException

public class Demo5 implements Cloneable{
	private int age;
	private LittleDemo little;
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Demo5 d = (Demo5)super.clone();
		d.little = (LittleDemo)this.little.clone();
		d.little.toString();
		return d;
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Demo5 d = new Demo5();
		d.age = 5;
		d.little = new LittleDemo();
		Demo5 d2 = (Demo5)d.clone();
		System.out.println("d == d2 :" + (d == d2));
		System.out.println("d.little == d2.little :" + (d.little == d2.little));
	}
}
class LittleDemo implements Cloneable{
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
}

父Demo5,子LittleDemo

相關文章