Java 克隆方式

Java克隆介绍

  在Java中存在两种克隆方式:

  1. 深克隆:不仅克隆对象本身,还克隆对象包含的引用所指向的所有对象。(通过实现Serilable接口)
  2. 浅克隆:仅克隆对象本身,不可隆对象中的引用指向的对象。(通过实现Cloneable接口)

代码实现

CloneableBO

package clone;

/**
 * 通过实现Cloneable接口来克隆
 *
 * @author zhao.hualuo
 * Create at 2021/12/31
 */
public class CloneableBO implements Cloneable {

    /** 编号 */
    private int id;

    /** 姓名 */
    private String name;

    /** 对象 */
    private CommonBO commonBO;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public CommonBO getCommonBO() {
        return commonBO;
    }

    public void setCommonBO(CommonBO commonBO) {
        this.commonBO = commonBO;
    }

    @Override
    public String toString() {
        return "CloneableBO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", commonBO=" + commonBO +
                '}';
    }

    @Override
    public CloneableBO clone() {
        try {
            CloneableBO clone = (CloneableBO) super.clone();
            // TODO: copy mutable state here, so the clone can't change the internals of the original
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

CommonBO

package clone;

import java.io.Serializable;

/**
 * 公共对象
 *
 * @author zhao.hualuo
 * Create at 2021/12/31
 */
public class CommonBO implements Serializable {

    /** 内容 */
    private String context;

    public CommonBO(String context) {
        this.context = context;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    @Override
    public String toString() {
        return "CommonBO{" +
                "context='" + context + '\'' +
                '}';
    }
}

SerializableBO

package clone;

import java.io.Serializable;

/**
 * 通过序列化方式实现克隆
 *
 * @author zhao.hualuo
 * Create at 2021/12/31
 */
public class SerializableBO implements Serializable {

    /** 编号 */
    private int id;

    /** 姓名 */
    private String name;

    /** 对象 */
    private CommonBO commonBO;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public CommonBO getCommonBO() {
        return commonBO;
    }

    public void setCommonBO(CommonBO commonBO) {
        this.commonBO = commonBO;
    }

    @Override
    public String toString() {
        return "SerializableBO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", commonBO=" + commonBO +
                '}';
    }
}

SerializableUtil

package clone;

import java.io.*;

/**
 * 序列化克隆工具
 *
 * @author zhao.hualuo
 * Create at 2021/12/31
 */
public class SerializableUtil {

    public static <T extends Serializable> T clone(T obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(obj);

        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        return (T) objectInputStream.readObject();
    }
}

MainTest

package clone;

import java.io.IOException;

/**
 * 克隆工具 测试
 *
 * @author zhao.hualuo
 * Create at 2021/12/31
 */
public class MainTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        CloneableBO cloneableBO = new CloneableBO();
        cloneableBO.setId(1);
        cloneableBO.setName("小赵");
        cloneableBO.setCommonBO(new CommonBO("我是内容1"));
        System.out.println("cloneable 复制前 初始内容:" + cloneableBO);

        CloneableBO cloneableBOCopy = cloneableBO.clone();
        cloneableBOCopy.getCommonBO().setContext("我是内容2");
        System.out.println("cloneable 复制后 初始内容:" + cloneableBO);
        System.out.println("cloneable 复制后 复制内容:" + cloneableBOCopy);

        SerializableBO serializableBO = new SerializableBO();
        serializableBO.setId(2);
        serializableBO.setName("小李");
        serializableBO.setCommonBO(new CommonBO("我是内容3"));

        System.out.println("serializable 复制前 初始内容:" + serializableBO);
        SerializableBO serializableBOCopy = SerializableUtil.clone(serializableBO);
        serializableBOCopy.getCommonBO().setContext("我是内容4");
        System.out.println("serializable 复制后 初始内容:" + serializableBO);
        System.out.println("serializable 复制后 复制内容:" + serializableBOCopy);
    }
}

执行结果
在这里插入图片描述

为什么推荐选择深克隆?

  基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化。这项检查是编译器完成的,不是在运行时抛出异常,这种方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总好过把问题留到运行时。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值