Java中的对象拷贝

我们在开发中有时候会经常需要进行对象拷贝的情况,举个例子

  public static void main(String[] args) {
        m1(o);
        m2(o);
    }
    public static void m1(Object o){
		//会对o进行修改
    }
    public static void m2(Object o){
		//会对o进行修改
    }

此时我们在m1和m2中就需要对入参参数进行拷贝并使用,否则会污染原参数到底其他方法产生问题。

浅拷贝

Java提供了clone()来实现对象的拷贝,但其默认拷贝是浅拷贝。
什么是浅拷贝?

public static void main(String[] args) throws Exception{
        TestClone testClone = new TestClone(1,"jwb", Collections.emptyList());
        TestClone clone = testClone.clone();

    }
    
class TestClone implements Cloneable{
    private int number;
    private String name;
    private List<String> list;
    
    @Override
    protected TestClone clone() throws CloneNotSupportedException {
        return (TestClone) super.clone();
    }
}

在这里插入图片描述
从断点中我们可以看到,源对象和克隆对象中的引用类型属性(String类型的name属性,List类型的list属性)的对象地址是相同的,即共享了同一个对象,这时候我们在源对象中或克隆对象中更改这些属性,都会造成另一个对象中的该属性发生改变,因为它们本身就是共有的同一个属性对象。

不止是默认的clone方法,我们平时经常使用的Spring提供的BeanUtils.copyProperties其实也是浅拷贝的

public static void main(String[] args) throws Exception{
        TestClone testClone = new TestClone(1,"jwb", Collections.emptyList());
//        TestClone clone = testClone.clone();
        TestClone clone = new TestClone();
        BeanUtils.copyProperties(testClone,clone);
    }

在这里插入图片描述

如何实现深拷贝?

  1. 重写对象的clone方法,手动实现
  2. 对象序列化,再反序列化为对象
  3. 各种工具类,其实现原理同样是基于java序列化的,如commons.lang3

第一种方法这里就不赘述了,我们这里演示一下第二种和第三种

fastjson
public static void main(String[] args) throws Exception{
        TestClone testClone = new TestClone(1,"jwb", Collections.emptyList());
        TestClone clone = JSON.parseObject(JSON.toJSONString(testClone),TestClone.class);
        System.out.println(testClone);
}

在这里插入图片描述

commons.lang3

 public static void main(String[] args) throws Exception{
        TestClone testClone = new TestClone(1,"jwb", new ArrayList<>());
        TestClone clone = SerializationUtils.clone(testClone);
        System.out.println(testClone);
    }

在这里插入图片描述
注意其底层是基于Java序列化的,因此克隆类必须实现Serializable接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值