浅克隆、深度克隆实现

引言

有些时候我们需要将java对象内容重写复制一份时(如我们需要将当前记录作废,重新插入一条记录时),可以重写new一个对象,也可以使用clone方法。实现Cloneable接口。

1.浅克隆:是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。

public class PersonVO implements Cloneable, Serializable {

    private static final long serialVersionUID = 319788853193121606L;

    private String personId;

    private String name;

    private RoleVO roleVO;

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
    @Test
    public void cloneTest()  throws CloneNotSupportedException{
        PersonVO personVO = new PersonVO();
        personVO.setName("person-name");
        personVO.setPersonId("123");
        RoleVO roleVO = new RoleVO();
        roleVO.setName("name");
        roleVO.setRoleId("23");
        personVO.setRoleVO(roleVO);

        PersonVO vo = (PersonVO) personVO.clone();
        vo.setName("clone-person-name");
        RoleVO rvo = vo.getRoleVO();
        rvo.setName("clone-name");

        LOGGER.info("personVO {}", personVO);
        LOGGER.info("vo {}", vo);
    }

//输出结果:
personVO PersonVO(personId=123, name=person-name, roleVO=RoleVO(roleId=23, name=clone-name))
vo PersonVO(personId=123, name=clone-person-name, roleVO=RoleVO(roleId=23, name=clone-name))

2.深度克隆:拷贝了所有,即能够做到原对象和新对象之间完全没有影响。

/**
 * 支持深度克隆
 * 必要条件
 * 1.实现Cloneable,Serializable接口
 * 2.重写clone方法
 * 3.clone方法改为public
 * 4.clone方法必须要支持创建新的对象而不是对象引用
 *
 */
@Data
@ToString
public class UserVO implements Cloneable, Serializable {

    private static final long serialVersionUID = 4804464826275613486L;

    private String userId;

    private String password;

    private Date date;

    private RoleVO roleVO;

    @Override
    public Object clone() {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            return ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != ois) {
                    ois.close();
                }
                if (null != oos) {
                    oos.close();
                }
                if (null != bos) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
  @Test
  public void deepCloneTest() {
        UserVO userVO = new UserVO();
        userVO.setDate(new Date());
        userVO.setPassword("123");
        userVO.setUserId("12");
        RoleVO roleVO = new RoleVO();
        roleVO.setName("name");
        roleVO.setRoleId("23");
        userVO.setRoleVO(roleVO);

        UserVO vo = (UserVO) userVO.clone();
        vo.setUserId("clone-12");
        RoleVO rvo = vo.getRoleVO();
        rvo.setName("clone-name");

        LOGGER.info("userVO {}", userVO);
        LOGGER.info("vo {}", vo);
    }

//输出结果:
userVO UserVO(userId=12, password=123, date=Sat Jun 20 17:25:11 CST 2020, roleVO=RoleVO(roleId=23, name=name))
vo UserVO(userId=clone-12, password=123, date=Sat Jun 20 17:25:11 CST 2020, roleVO=RoleVO(roleId=23, name=clone-name))

结果可以看出浅克隆引用修改会相互之间影响,而深度克隆不会。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值