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();
}
   }
相关文章
相关标签/搜索