使用Lang3实现深拷贝(SerializationUtils.clone())

本文介绍了对象克隆的用途,包括保护原始对象、避免共享引用和提高性能。区分了浅拷贝和深拷贝的概念,浅拷贝仅复制顶层结构,而深拷贝则递归复制所有嵌套对象。通过ApacheCommonsLang的SerializationUtils.clone()方法展示了如何在Java中实现深拷贝,强调了对象需实现Serializable接口。同时提到了GoogleGson作为另一种实现深拷贝的手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Lang3实现深拷贝(SerializationUtils.clone())


先通过几个问题来引出题目:

对象克隆

什么情况下需要对一个对象进行克隆?

1、保护原始对象:有时候我们需要保护一个对象的原始状态,以便在之后的操作中可以对其进行修改而不影响原始对象。通过克隆对象,我们可以创建一个副本来进行操作,而不改变原始对象的状态。
2、避免共享引用:在某些情况下,多个对象可能引用同一个对象,如果对其中一个对象进行修改,会影响其他对象的行为。通过克隆对象,我们可以创建一个独立的副本,使得每个对象都有自己的引用,互不干扰。
3、提高性能:有时候创建一个新对象的代价比克隆一个已有对象要小。在这种情况下,克隆对象可以避免重复的初始化操作,提高程序的性能。

深拷贝和浅拷贝的区别

浅拷贝:
浅拷贝创建一个新对象,该对象与原始对象共享一部分内存,包括对象的引用。这意味着新对象和原始对象引用相同的子对象。
当进行浅拷贝时,只复制对象的顶层结构,而不会递归复制内部嵌套对象。
修改浅拷贝对象的子对象会影响原始对象中相应的子对象,因为它们引用相同的内存地址。

深拷贝:
深拷贝创建一个全新的对象,该对象和原始对象完全独立,包括对象的引用和内部嵌套对象。
深拷贝会递归复制原始对象及其所有嵌套对象,确保每个对象都是全新的。
修改深拷贝对象的子对象不会影响原始对象,因为它们是完全独立的。

深拷贝代码示例

Apache Commons Lang是一个通用的Java工具库,其中包括了对对象进行深拷贝的方法。具体用法可以参考下面的代码示例:

import org.apache.commons.lang3.SerializationUtils;

public class DeepCopyExample {
    public static void main(String[] args) {
        // 创建一个原始对象
        Person original = new Person("John", new Address("Main Street"));

        // 使用SerializationUtils深拷贝对象
        Person copy = SerializationUtils.clone(original);

        // 改变原始对象的属性
        original.setName("Mike");
        original.getAddress().setStreet("Second Street");

        // 输出结果
        System.out.println("Original: " + original); // Original: Person{name='Mike', address=Address{street='Second Street'}}
        System.out.println("Copy: " + copy); // Copy: Person{name='John', address=Address{street='Main Street'}}
    }
}

class Person implements Serializable {
    private String name;
    private Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

class Address implements Serializable {
    private String street;

    public Address(String street) {
        this.street = street;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

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

需要注意的是,使用SerializationUtils.clone()方法克隆对象时,该对象必须实现Serializable接口,否则将抛出SerializationException异常。

此外,Google Gson中的方法也可以实现深拷贝。

// 示例代码
SourceBean source = new SourceBean();
source.setName("John");
source.setAge(30);

Gson gson = new Gson();

// 将source对象转换为JSON字符串
String json = gson.toJson(source);

// 将JSON字符串转换回对象,这将得到一个新的对象
TargetBean target = gson.fromJson(json, TargetBean.class);

System.out.println(target.getName()); // Output: "John"
System.out.println(target.getAge());  // Output: 30

// 修改source对象的属性,不会影响target对象
source.setAge(40);
System.out.println(target.getAge());  // Output: 30 (没有变化)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值