对照下面的例子很容易看出:
当一个对象赋值给另一个对象变量时,是相同的引用,公用这个对象实例;
浅拷贝,需要实现Cloneable这个标记接口,然后自行实现clone方法,clone方法的默认就是浅拷贝;注意:当对象中成员变量都是基本类型或者不可变量如String的时候,浅拷贝是安全的。
但是当变量中存在子对象变量的引用时,就需要深拷贝了,因为浅拷贝并不会对子对象进行clone,这样就造成子对象变为共享域,对象和对象副本都会造成它的状态等改变。因此,深拷贝就类似于递归的把对象本身及对象中包含的对象都进行clone。

package learning.copy;

/**
 *@className SuperficialCopy
 *@description :浅拷贝,当对象本身不含有子对象引用的时候,浅拷贝是安全的    
 *                  clone方法的默认就是浅拷贝,深拷贝需要自己去实现。
 *@author Wanggd @date 2017年5月27日上午11:20:23
 */
public class SuperficialCopy implements Cloneable{

    String name;
    int age;

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

    @Override
    public Object clone() throws CloneNotSupportedException{

        Object o = super.clone();
        return o;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        SuperficialCopy obj1 = new SuperficialCopy("Kevin",20);

        SuperficialCopy copyObj = (SuperficialCopy) obj1.clone();
        copyObj.age = 80;
        System.out.println("object1's age = " + obj1.age );
        //结果:object1's age = 20

        SuperficialCopy obj2 = obj1;
        obj2.age = 90;
        System.out.println("changed by obj2 object1's age = " + obj1.age );
        //changed by obj2 object1's age = 90
    }

}
package learning.copy;

/**
 *@className SuperficialCopyHasObj
 *@description :浅拷贝,当浅拷贝发生在对象含有子对象引用的时候,浅拷贝就不再是安全的。 
 *@author Wanggd @date 2017年5月27日上午11:21:48
 *
 */
public class SuperficialCopyHasObj implements Cloneable{

    private String name;
    private int age;
    private Inner inner;

    SuperficialCopyHasObj(String name,int age,Inner inner){
        this.age = age;
        this.name = name;
        this.inner = inner;
    }

    @Override
    public Object clone() throws CloneNotSupportedException{

        Object o = super.clone();
        return o;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        SuperficialCopyHasObj obj1 = new SuperficialCopyHasObj("Kevin",20,new Inner("who",66));
        System.out.println("Before object1's inner name = " + obj1.inner.getInnerName() );
        //结果:Before object1's inner name = who

        SuperficialCopyHasObj copyObj = (SuperficialCopyHasObj) obj1.clone();
        copyObj.age = 80;
        System.out.println("object1's age = " + obj1.age );
        //结果:object1's age = 20

        copyObj.inner.setInnerName("what");
        System.out.println("object1's inner name = " + obj1.inner.getInnerName() );
        //object1's inner name = what

    }

}
package learning.copy;

/**
 *@className DeepCopy
 *@description :深度拷贝,对象本身及包含的对象引用也要clone    
 *@author Wanggd @date 2017年5月27日上午11:19:23
 */
public class DeepCopy implements Cloneable{
    private String name;
    private int age;
    private Inner inner;

    DeepCopy(String name, int age, Inner inner){
        this.name = name;
        this.age = age;
        this.inner = inner;
    }

    public Object clone(){
        DeepCopy o = null;
        try {
            o = (DeepCopy)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        o.inner = (Inner)inner.clone();
        return o;
    }

    public static void main(String[] args) {
        Inner inner = new Inner("I'm inner",10);
        DeepCopy obj1 = new DeepCopy("I'm kevin", 20, inner);

        DeepCopy copyObj = (DeepCopy) obj1.clone();
        copyObj.setAge(88);
        copyObj.inner.setInnerAge(90);
        copyObj.inner.setInnerName("changes");

        System.out.println("obj1's age=" + obj1.age + ",obj1's inner name=" + obj1.inner.getInnerName());
        //结果:obj1's age=20,obj1's inner name=I'm inner
    }

    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 Inner getInner() {
        return inner;
    }

    public void setInner(Inner inner) {
        this.inner = inner;
    }


}

class Inner implements Cloneable{

    private String innerName;
    private int innerAge;

    Inner(String innerName, int innerAge){
        this.innerAge = innerAge;
        this.innerName = innerName;
    }

    public String getInnerName() {
        return innerName;
    }

    public void setInnerName(String innerName) {
        this.innerName = innerName;
    }

    public int getInnerAge() {
        return innerAge;
    }

    public void setInnerAge(int innerAge) {
        this.innerAge = innerAge;
    }

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

}
posted on 2017-05-24 10:59  菜码农先生  阅读(118)  评论(0编辑  收藏  举报