[Java] 浅拷贝与深拷贝

来源:互联网 发布:淘宝旺旺聊天刷单禁词 编辑:程序博客网 时间:2024/06/16 04:47

Java 中的拷贝分为浅拷贝和深拷贝两种,其中浅拷贝指只拷贝按值传递的数据类型,如基本数据类型、String 类型;而深拷贝除了拷贝浅拷贝的内容外,还负责拷贝引用类型的数据

一、浅拷贝示例:

主要部分为:

@Overrideprotected Object clone() {     Object obj = null;     try {         obj = super.clone();     } catch (Exception e) {         e.printStackTrace();     }     return obj; }

详细示例如下:

package com.kascend.test.copy;/** * 浅拷贝对象 * * @author wengliemiao */public class SimpleCopy implements Cloneable {    private int id;    private String name;    private String signature;    /**     * 获取 id     *     * @return id     */    public int getId() {        return id;    }    /**     * 设置 id     *     * @param id     */    public void setId(int id) {        this.id = id;    }    /**     * 获取 name     *     * @return name     */    public String getName() {        return name;    }    /**     * 设置 name     *     * @param name     */    public void setName(String name) {        this.name = name;    }    /**     * 获取 signature     *     * @return signature     */    public String getSignature() {        return signature;    }    /**     * 设置 signature     *     * @param signature     */    public void setSignature(String signature) {        this.signature = signature;    }    @Override    protected Object clone() {        Object obj = null;        try {            obj = super.clone();        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }    @Override    public String toString() {        return "SimpleCopy{" +                "id=" + id +                ", name='" + name + '\'' +                ", signature='" + signature + '\'' +                '}';    }}
package com.kascend.test.copy;/** * 浅拷贝测试类 * * @author wengliemiao */public class CopyTest {    public static void main(String[] args) {        SimpleCopy simpleCopy = new SimpleCopy();        simpleCopy.setId(1);        simpleCopy.setName("wlmmm");        simpleCopy.setSignature("a java programmer");        System.out.println("浅拷贝前: ");        System.out.println(simpleCopy);        SimpleCopy newSimpleCopy = (SimpleCopy) simpleCopy.clone();        newSimpleCopy.setSignature("a handsome java programmer");        System.out.println("浅拷贝的对象: ");        System.out.println(newSimpleCopy);        System.out.println("浅拷贝后: ");        System.out.println(simpleCopy);    }}

输出为:
浅拷贝输出

二、深拷贝示例:

主要部分为:

@Overrideprotected Object clone() {     DeepCopy obj = null;     try {         obj = (DeepCopy) super.clone();         obj.setPosition((Position) obj.getPosition().clone());     } catch (Exception e) {         e.printStackTrace();     }     return obj; }

详细示例如下:

package com.kascend.test.copy;/** * 深拷贝对象 * * @author wengliemiao */public class DeepCopy implements Cloneable {    private int id;    private String name;    private String signature;    private Position position;    /**     * 获取 id     *     * @return id     */    public int getId() {        return id;    }    /**     * 设置 id     *     * @param id     */    public void setId(int id) {        this.id = id;    }    /**     * 获取 name     *     * @return name     */    public String getName() {        return name;    }    /**     * 设置 name     *     * @param name     */    public void setName(String name) {        this.name = name;    }    /**     * 获取 signature     *     * @return signature     */    public String getSignature() {        return signature;    }    /**     * 设置 signature     *     * @param signature     */    public void setSignature(String signature) {        this.signature = signature;    }    /**     * 获取 position     *     * @return position     */    public Position getPosition() {        return position;    }    /**     * 设置 position     *     * @param position     */    public void setPosition(Position position) {        this.position = position;    }    @Override    protected Object clone() {        DeepCopy obj = null;        try {            obj = (DeepCopy) super.clone();            obj.setPosition((Position) obj.getPosition().clone());        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }    @Override    public String toString() {        return "DeepCopy{" +                "id=" + id +                ", name='" + name + '\'' +                ", signature='" + signature + '\'' +                ", position=" + position +                '}';    }}
package com.kascend.test.copy;/** * 地理位置对象 * * @author wengliemiao */public class Position implements Cloneable {    /**     * 省份     */    private String province;    /**     * 城市     */    private String city;    public Position(String province, String city) {        this.province = province;        this.city = city;    }    /**     * 获取 province     *     * @return province     */    public String getProvince() {        return province;    }    /**     * 设置 province     *     * @param province     */    public void setProvince(String province) {        this.province = province;    }    /**     * 获取 city     *     * @return city     */    public String getCity() {        return city;    }    /**     * 设置 city     *     * @param city     */    public void setCity(String city) {        this.city = city;    }    @Override    protected Object clone() {        Object obj = null;        try {            obj = super.clone();        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }    @Override    public String toString() {        return "Position{" +                "province='" + province + '\'' +                ", city='" + city + '\'' +                '}';    }}
package com.kascend.test.copy;/** * 深拷贝测试类 * * @author wengliemiao */public class DeepCopyTest {    public static void main(String[] args) {        DeepCopy deepCopy = new DeepCopy();        deepCopy.setId(1);        deepCopy.setName("wlmmm");        deepCopy.setSignature("a java programmer");        deepCopy.setPosition(new Position("浙江", "杭州"));        System.out.println("深拷贝前: ");        System.out.println(deepCopy);        DeepCopy newDeepCopy = (DeepCopy) deepCopy.clone();        newDeepCopy.setSignature("a handsome java programmer");        newDeepCopy.getPosition().setProvince("江西");        newDeepCopy.getPosition().setCity("上饶");        System.out.println("深拷贝的对象: ");        System.out.println(newDeepCopy);        System.out.println("深拷贝后: ");        System.out.println(deepCopy);    }}

输出为:
深拷贝输出

深拷贝需要注意的地方:需要递归拷贝所有的引用类型属性,如果有一个没有正确实现拷贝,则会失败。

三、序列化方式实现深拷贝

主要部分为:

@Overrideprotected Object clone() {    Object obj = null;    try {        // 写入到流中        ByteArrayOutputStream bao = new ByteArrayOutputStream();        ObjectOutputStream oo = new ObjectOutputStream(bao);        oo.writeObject(this);        // 从流中读取        ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());        ObjectInputStream oi = new ObjectInputStream(bai);        obj = oi.readObject();    } catch (Exception e) {        e.printStackTrace();    }    return obj;}

详细示例如下:

package com.kascend.test.copy;import java.io.*;/** * 深拷贝序列化对象 * * @author wengliemiao */public class DeepCopySerializer implements Serializable {    private static final long serialVersionUID = 2613335614834345944L;    private int id;    private String name;    private String signature;    private PositionSerializer positionSerializer;    /**     * 获取 id     *     * @return id     */    public int getId() {        return id;    }    /**     * 设置 id     *     * @param id     */    public void setId(int id) {        this.id = id;    }    /**     * 获取 name     *     * @return name     */    public String getName() {        return name;    }    /**     * 设置 name     *     * @param name     */    public void setName(String name) {        this.name = name;    }    /**     * 获取 signature     *     * @return signature     */    public String getSignature() {        return signature;    }    /**     * 设置 signature     *     * @param signature     */    public void setSignature(String signature) {        this.signature = signature;    }    /**     * 获取 positionSerializer     *     * @return positionSerializer     */    public PositionSerializer getPositionSerializer() {        return positionSerializer;    }    /**     * 设置 positionSerializer     *     * @param positionSerializer     */    public void setPositionSerializer(PositionSerializer positionSerializer) {        this.positionSerializer = positionSerializer;    }    @Override    public String toString() {        return "DeepCopySerializer{" +                "id=" + id +                ", name='" + name + '\'' +                ", signature='" + signature + '\'' +                ", positionSerializer=" + positionSerializer +                '}';    }    @Override    protected Object clone() {        Object obj = null;        try {            // 写入到流中            ByteArrayOutputStream bao = new ByteArrayOutputStream();            ObjectOutputStream oo = new ObjectOutputStream(bao);            oo.writeObject(this);            // 从流中读取            ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());            ObjectInputStream oi = new ObjectInputStream(bai);            obj = oi.readObject();        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }}
package com.kascend.test.copy;import java.io.Serializable;/** * 地理位置序列化对象 * * @author wengliemiao */public class PositionSerializer implements Serializable {    private static final long serialVersionUID = 4079422724081087207L;    private String province;    private String city;    public PositionSerializer(String province, String city) {        this.province = province;        this.city = city;    }    /**     * 获取 province     *     * @return province     */    public String getProvince() {        return province;    }    /**     * 设置 province     *     * @param province     */    public void setProvince(String province) {        this.province = province;    }    /**     * 获取 city     *     * @return city     */    public String getCity() {        return city;    }    /**     * 设置 city     *     * @param city     */    public void setCity(String city) {        this.city = city;    }    @Override    public String toString() {        return "Position2{" +                "province='" + province + '\'' +                ", city='" + city + '\'' +                '}';    }}
package com.kascend.test.copy;/** * 序列化实现深拷贝测试类 * * @author wengliemiao */public class DeepCopySerializerTest {    public static void main(String[] args) {        DeepCopySerializer deepCopySerializer = new DeepCopySerializer();        deepCopySerializer.setId(1);        deepCopySerializer.setName("wlmmm");        deepCopySerializer.setSignature("a java programmer");        deepCopySerializer.setPositionSerializer(new PositionSerializer("浙江", "杭州"));        System.out.println("序列化方式深拷贝前: ");        System.out.println(deepCopySerializer);        DeepCopySerializer newDeepCopy = (DeepCopySerializer) deepCopySerializer.clone();        newDeepCopy.setSignature("a handsome java programmer");        newDeepCopy.getPositionSerializer().setProvince("江西");        newDeepCopy.getPositionSerializer().setCity("上饶");        System.out.println("序列化方式深拷贝对象: ");        System.out.println(newDeepCopy);        System.out.println("序列化方式深拷贝后: ");        System.out.println(deepCopySerializer);    }}

输出为:
序列化方式实现深拷贝

小结:序列化实现深拷贝的方式在很多框架中应用,可省去实现 Cloneable 接口的复杂繁琐的操作。如常用的 memcached 缓存,要求需要放入缓存中的对象实现 Serializable 接口。

注:序列化实现深拷贝参考自: java对象克隆以及深拷贝和浅拷贝