淺拷貝和深拷貝

淺拷貝:

package algorithm;

import java.util.ArrayList;

public class ShallowCopy implements Cloneable{
	private String name;
	private ArrayList<String> list = new ArrayList<String>();
	public void printName(){
		System.out.println(this.name);
	}
	public void setName(String name) {
        this.name = name;
    }
	public void addListValue(String value){
		this.list.add(value);
	}
	public void printlnList() {
        System.out.println(this.list);
    }
	public ShallowCopy() {
		System.out.println("shallow copy test");
	}
	/**
	 * 
	 * 淺拷貝是指拷貝對象時僅僅拷貝對象本身(包括對象中的基本變量),
	 * 而不拷貝對象包含的引用指向的對象。深拷貝不僅拷貝對象本身,
	 * 而且拷貝對象包含的引用指向的所有對象。
	 * 
	 */
	@Override
	protected ShallowCopy clone() throws CloneNotSupportedException {
		return (ShallowCopy) super.clone();
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		ShallowCopy shallow = new ShallowCopy();
        shallow.setName("yhx");
        shallow.addListValue("Java");
        
        shallow.printName();
        shallow.printlnList();
        
        ShallowCopy shallowCopy = shallow.clone(); // 克隆
        // 打印出兩個對象的地址
        System.out.println(shallow);
        System.out.println(shallowCopy);
        
        shallowCopy.addListValue("Python");
        
        shallowCopy.printlnList(); 
        shallowCopy.printName(); 
        
        shallowCopy.setName("hello");
        
        shallow.printName(); // 輸出 yhx
        shallowCopy.printName();
        shallow.printlnList(); // // 輸出 Java,Python
        
        /**
         * 從結果中我們可以看到
			拷貝時候雖然創建了新的對象,但是並沒有調用構造方法
			對象中的引用對象並沒有拷貝,引用的地址還是和原對象一致
			基本類型或者 String 默認會拷貝
			像這種只拷貝了對象本身,而對象中引用數據類型沒有被拷貝的拷貝方式,叫做淺拷貝。
			淺拷貝往往存在一定的風險,因爲引用對象的地址拷貝前後一致,所以對象的值很容易被更改,不安全。
         */
	}
}


深拷貝:

①:

package algorithm;

import java.util.ArrayList;

public class DeepCopy implements Cloneable{
	private String name;
    private ArrayList<String> list = new ArrayList<>();
    public void printlnName() {
        System.out.println(this.name);
    }
    public void setName(String name) {
        this.name = name;
    }
    public void addListValue(String value) {
        this.list.add(value);
    }
    public void printlnList() {
        System.out.println(this.list);
    }
    public DeepCopy() {
        System.out.println("deep copy test");
    }
    @Override
    protected DeepCopy clone() throws CloneNotSupportedException {
    	DeepCopy clone = (DeepCopy) super.clone();
        clone.list = (ArrayList<String>) this.list.clone();
        return clone;
    }
    public static void main(String[] args) throws CloneNotSupportedException {
    	DeepCopy deep = new DeepCopy();
        deep.setName("yhx");
        deep.addListValue("Java");
        deep.printlnName(); 
        deep.printlnList(); 
        DeepCopy deepCopy = deep.clone(); // 克隆
     // 打印出兩個對象的地址
        System.out.println(deep);
        System.out.println(deepCopy);
        deepCopy.printlnList();
        deepCopy.addListValue("Python");
        deepCopy.printlnList();
        deepCopy.printlnName();
        deepCopy.setName("hello");
        deep.printlnName();
        deep.printlnList();
        //如果字段上有 final 修飾,就不能實現 clone 方法了,因爲 final 變量不能再次被賦值。
	}
}


②串行化深拷貝:

package algorithm;

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

public class DeepCopyBySeriablizable{
	//串行化很耗時,在一些框架中,我們便可以感受到,它們往往將對象進行串行化後進行傳遞,耗時較多。
	public static void main(String[] args) 
			throws OptionalDataException, ClassNotFoundException, IOException {
		long t1 = System.currentTimeMillis();
        Professor2 p = new Professor2("wangwu", 50);
        Student2 s1 = new Student2("zhangsan", 18, p);
        Student2 s2 = (Student2) s1.deepClone();
        s2.p.name = "lisi";
        s2.p.age = 30;
        System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 學生1的教授不改變。
        System.out.println("name=" + s2.p.name + "," + "age=" + s2.p.age);
        long t2 = System.currentTimeMillis();
        System.out.println(t2-t1);
	}
}
class Professor2 implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String name;
    int age;
 
    Professor2(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
 
class Student2 implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String name;// 常量對象。
    int age;
    Professor2 p;// 學生1和學生2的引用值都是一樣的。
 
    Student2(String name, int age, Professor2 p) {
        this.name = name;
        this.age = age;
        this.p = p;
    }
 
    public Object deepClone() throws IOException, OptionalDataException,
            ClassNotFoundException {
        // 將對象寫到流裏
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(this);
        // 從流裏讀出來
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (oi.readObject());
    }
 
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章