深克隆和浅克隆

版权声明:本文为博主原创文章,未经博主允许不得转载!!! https://blog.csdn.net/qq_19107011/article/details/79491982

深克隆就是:进行克隆以后,引用对象的地址改变了。
浅克隆就是:进行克隆以后,引用对象的地址没有改变。
二种克隆都会重新复制基本数据类型(int,long等非final属性,包括string)

举个栗子:

package com.nameshame;

import java.util.ArrayList;

public class TestClone {
    public static void main(String[] args) {
        ArrayList<TestClone> a = new ArrayList<TestClone>();
        a.add(new TestClone());
        TestClone obj1 =  a.get(0);

        ArrayList a2 = (ArrayList) a.clone();

        TestClone obj2 =  a.get(0);

        System.out.println("克隆前后是否是同一个对象:"+(obj1==obj2));

    }
}

ayList的clone这个方法是属于哪一种克隆方法。
输出为:

克隆前后是否是同一个对象:true

所以,它属于浅克隆,图解如下:
浅克隆
下面看看我们把程序改成,对ArrayList进行深克隆。

package com.nameshame;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

public class TestClone implements Serializable{
    public static void main(String[] args) throws Exception{
        ArrayList<TestClone> a = new ArrayList<TestClone>();
        a.add(new TestClone());
        TestClone obj1 =  a.get(0);

        //使用序列化,进行深克隆
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(a);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        a = (ArrayList) ois.readObject();


        TestClone obj2 =  a.get(0);

        System.out.println("克隆前后是否是同一个对象:"+(obj1==obj2));

    }
}

程序的输出为

克隆前后是否是同一个对象:false

所以我们使用序列化和反序列化,进行通过二进制进行对象的深克隆。
图解如下:
深克隆
所以,从上面二个图就可以看出一个重要的地方。就是深克隆比浅克隆多了对对象里面引用对象的克隆操作。



之外,说下深克隆的通用实现。
如果类A需要进行深克隆。那么可以重新clone方法,然后在方法new一个新的对象返回。
这个就是通用的实现了。
同时A类需要实现Cloneable接口,这是一个标记接口。
主要就这2点。
告辞!

猜你喜欢

转载自blog.csdn.net/qq_19107011/article/details/79491982