使用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 (没有变化)

commons-lang3.3.1.jar、Apache Commons包中的一个,包含了一些数据类型工具类,是java.lang.*的扩展。必须使用的jar包。为JRE5.0+的更好的版本所提供 Jar文件包含的类: META-INF/MANIFEST.MFMETA-INF/LICENSE.txtMETA-INF/NOTICE.txtorg.apache.commons.lang.ArrayUtils.class org.apache.commons.lang.BitField.class org.apache.commons.lang.BooleanUtils.class org.apache.commons.lang.CharEncoding.class org.apache.commons.lang.CharRange.class org.apache.commons.lang.CharSet.class org.apache.commons.lang.CharSetUtils.class org.apache.commons.lang.CharUtils.class org.apache.commons.lang.ClassUtils.class org.apache.commons.lang.Entities$ArrayEntityMap.class org.apache.commons.lang.Entities$BinaryEntityMap.class org.apache.commons.lang.Entities$EntityMap.class org.apache.commons.lang.Entities$HashEntityMap.class org.apache.commons.lang.Entities$LookupEntityMap.class org.apache.commons.lang.Entities$MapIntMap.class org.apache.commons.lang.Entities$PrimitiveEntityMap.class org.apache.commons.lang.Entities$TreeEntityMap.class org.apache.commons.lang.Entities.class org.apache.commons.lang.IllegalClassException.class org.apache.commons.lang.IncompleteArgumentException.class org.apache.commons.lang.IntHashMap$Entry.class org.apache.commons.lang.IntHashMap.class org.apache.commons.lang.LocaleUtils.class org.apache.commons.lang.NotImplementedException.class org.apache.commons.lang.NullArgumentException.class org.apache.commons.lang.NumberRange.class org.apache.commons.lang.NumberUtils.class org.apache.commons.lang.ObjectUtils$Null.class org.apache.commons.lang.ObjectUtils.class org.apache.commons.lang.RandomStringUtils.class org.apache.commons.lang.SerializationException.class org.apache.commons.lang.SerializationUtils.class org.apache.commons.lang.StringEscapeUtils.class org.apache.commons.lang.StringUtils.class org.apache.commons.lang.SystemUtils.class org.apache.commons.lang.UnhandledException.class org.apache.commons.lang.Validate.class org.apache.commons.lang.WordUtils.class org.apache.commons.lang.builder.CompareToBuilder.class org.apache.commons.lang.builder.EqualsBuilder.class org.apache.commons.lang.builder.HashCodeBuilder.class org.apache.commons.lang.builder.ReflectionToStringBuilder$1.class org.apache.commons.lang.builder.ReflectionToStringBuilder.class org.apache.commons.lang.builder.StandardToStringStyle.class org.apache.commons.lang.builder.ToStringBuilder.class org.apache.commons.lang.builder.ToStringStyle$DefaultToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$MultiLineToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$NoFieldNameToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$ShortPrefixToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$SimpleToStringStyle.class org.apache.commons.lang.builder.ToStringStyle.class org.apache.commons.lang.enum.Enum$Entry.class org.apache.commons.lang.enum.Enum.class org.apache.commons.lang.enum.EnumUtils.class org.apache.commons.lang.enum.ValuedEnum.class org.apache.commons.lang.enums.Enum$Entry.class org.apache.commons.lang.enums.Enum.class org.apache.commons.lang.enums.EnumUtils.class org.apache.commons.lang.enums.ValuedEnum.class org.apache.commons.lang.exception.ExceptionUtils.class org.apache.commons.lang.exception.Nestable.class org.apache.commons.lang.exception.NestableDelegate.class org.apache.commons.lang.exception.NestableError.class org.apache.commons.lang.exception.NestableException.class org.apache.commons.lang.exception.NestableRuntimeException.class org.apache.commons.lang.math.DoubleRange.class org.apache.commons.lang.math.FloatRange.class org.apache.commons.lang.math.Fraction.class org.apache.commons.lang.math.IntRange.class org.apache.commons.lang.math.JVMRandom.class org.apache.commons.lang.math.LongRange.class org.apache.commons.lang.math.NumberRange.class org.apache.commons.lang.math.NumberUtils.class org.apache.commons.lang.math.RandomUtils.class org.apache.commons.lang.math.Range.class org.apache.commons.lang.mutable.Mutable.class org.apache.commons.lang.mutable.MutableBoolean.class org.apache.commons.lang.mutable.MutableByte.class org.apache.commons.lang.mutable.MutableDouble.class org.apache.commons.lang.mutable.MutableFloat.class org.apache.commons.lang.mutable.MutableInt.class org.apache.commons.lang.mutable.MutableLong.class org.apache.commons.lang.mutable.MutableObject.class org.apache.commons.lang.mutable.MutableShort.class org.apache.commons.lang.text.CompositeFormat.class org.apache.commons.lang.text.StrBuilder$StrBuilderReader.class org.apache.commons.lang.text.StrBuilder$StrBuilderTokenizer.class org.apache.commons.lang.text.StrBuilder$StrBuilderWriter.class org.apache.commons.lang.text.StrBuilder.class org.apache.commons.lang.text.StrLookup$MapStrLookup.class org.apache.commons.lang.text.StrLookup.class org.apache.commons.lang.text.StrMatcher$CharMatcher.class org.apache.commons.lang.text.StrMatcher$CharSetMatcher.class org.apache.commons.lang.text.StrMatcher$NoMatcher.class org.apache.commons.lang.text.StrMatcher$StringMatcher.class org.apache.commons.lang.text.StrMatcher$TrimMatcher.class org.apache.commons.lang.text.StrMatcher.class org.apache.commons.lang.text.StrSubstitutor.class org.apache.commons.lang.text.StrTokenizer.class org.apache.commons.lang.time.DateFormatUtils.class org.apache.commons.lang.time.DateUtils$DateIterator.class org.apache.commons.lang.time.DateUtils.class org.apache.commons.lang.time.DurationFormatUtils$Token.class org.apache.commons.lang.time.DurationFormatUtils.class org.apache.commons.lang.time.FastDateFormat$CharacterLiteral.class org.apache.commons.lang.time.FastDateFormat$NumberRule.class org.apache.commons.lang.time.FastDateFormat$PaddedNumberField.class org.apache.commons.lang.time.FastDateFormat$Pair.class org.apache.commons.lang.time.FastDateFormat$Rule.class org.apache.commons.lang.time.FastDateFormat$StringLiteral.class org.apache.commons.lang.time.FastDateFormat$TextField.class org.apache.commons.lang.time.FastDateFormat$TimeZoneDisplayKey.class org.apache.commons.lang.time.FastDateFormat$TimeZoneNameRule.class org.apache.commons.lang.time.FastDateFormat$TimeZoneNumberRule.class org.apache.commons.lang.time.FastDateFormat$TwelveHourField.class org.apache.commons.lang.time.FastDateFormat$TwentyFourHourField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitMonthField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitNumberField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitYearField.class org.apache.commons.lang.time.FastDateFormat$UnpaddedMonthField.class org.apache.commons.lang.time.FastDateFormat$UnpaddedNumberField.class org.apache.commons.lang.time.FastDateFormat.class org.apache.commons.lang.time.StopWatch.class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值