java 深拷貝

obj.clone().getClass()==obj.getClass(),即它們具備相同的類型。還有一點,由於只是簡單的將對象的空間進行復 制,因此若是類具備引用類型的實例變量的話,也只是將這個引用進行拷貝,並不複製其引用的對象。這就致使拷貝對象的引用實例變量與原對象的指向相同的對 象,這就是傳說中的「淺拷貝」。若是實例變量引用的對象是不可變的,相似於String,則拷貝對象與原對象不能互相影響,這樣的拷貝是成功的。可是若是 引用的是可變對象,它們就會影響彼此,對於成功的拷貝而言,這是不容許的。能夠對可變的實例變量對象進行特殊處理,以實現拷貝對象和原對象不能相互影響的 「深拷貝」。java

      因爲Object.clone()方法是protected的,因此它只能在lang包中的類或是其子類的方法內部被調用,因此,若是像下面這樣調用,會 編譯出錯,在Person kobe_bak=kobe.clone();報錯,說clone只能在Object的protected做用域訪問。
app

一個類能夠被clone,必須知足兩點:
第一,它必須實現了Cloneable接口,不然會拋出CloneNotSupportedException異常。
第二,它必須提供一個public的clone方法,也就是重寫Object.clone()方法,不然編譯不能經過。
第三,對於存在可變域的類,在clone方法中須要對這些可變域進行拷貝。字體


package test.javacopy;

import java.util.Date;

/**
 * Created by Administrator on 2016/1/5.
 */
public class JavaCopy implements Cloneable {

    private String name;
    private int age;
    private Date date;
    private TestCopy testcopy;


    public JavaCopy(String name,int age){
        this.name = name;
        this.age = age;
    }

    public JavaCopy clone(){
        JavaCopy javaCopy = null;
        try {
            javaCopy = (JavaCopy)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return javaCopy;
    }

    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 Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public TestCopy getTestcopy() {
        return testcopy;
    }

    public void setTestcopy(TestCopy testcopy) {
        this.testcopy = testcopy;
    }
}
package test.javacopy;

import java.io.Serializable;
import java.util.Date;

/**
 * Created by Administrator on 2016/1/5.
 */
public class TestCopy implements Serializable,Cloneable{

    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public TestCopy clone(){
        TestCopy testCopy = null;
        try {
            testCopy = (TestCopy)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return testCopy;
    }

    public static void main(String args[]) {
        TestCopy testcopy = new TestCopy();
        testcopy.setName("javaCopy");

        JavaCopy javaCopy = new JavaCopy("123", 123);
        javaCopy.setDate(new Date());
        javaCopy.setTestcopy(testcopy);
        JavaCopy javaCopy1 = javaCopy.clone();

        System.out.println("===javaCopy1===" + javaCopy1.getName() + "age"
            + javaCopy1.getAge() + "date" + javaCopy1.getDate());

        javaCopy1.setName("321");
        javaCopy1.setAge(321);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        javaCopy.setDate(new Date());
        javaCopy.getTestcopy().setName("javaCopy1");
        System.out.println("===javaCopy=== name" + javaCopy.getName());
        System.out.println("===javaCopy1=== name" + javaCopy1.getName());

        System.out.println("===javaCopy=== age" + javaCopy.getAge());
        System.out.println("===javaCopy1=== age" + javaCopy1.getAge());

        System.out.println("===javaCopy=== date" + javaCopy.getDate());
        System.out.println("===javaCopy1=== date" + javaCopy1.getDate());

        System.out.println("===javaCopy=== testcopy name" + javaCopy.getTestcopy().getName());
        System.out.println("===javaCopy1=== testcopy name" + javaCopy1.getTestcopy().getName());
    }
}

執行的結果:this

===javaCopy1===123age123dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== name123
===javaCopy1=== name321
===javaCopy=== age123
===javaCopy1=== age321
===javaCopy=== dateTue Jan 05 13:52:11 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy1
3d

注意添加的粗字體的代碼(深拷貝)
code

    public JavaCopy clone(){
        JavaCopy javaCopy = null;
        try {
            javaCopy = (JavaCopy)super.clone();
            
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return javaCopy;
    }

執行結果:對象

===javaCopy=== dateTue Jan 05 13:55:15 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:55:13 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy
接口

jdk中的arraylist深拷貝實現:element

   public Object clone() {
try {
    ArrayList<E> v = (ArrayList<E>) super.clone();
    v.elementData = Arrays.copyOf(elementData, size);
    v.modCount = 0;
    return v;
} catch (CloneNotSupportedException e) {
    // this shouldn't happen, since we are Cloneable
    throw new InternalError();
}
   }
相關文章
相關標籤/搜索