SerializationUtils.clone()提供基于序列化的深拷贝,无需实现Cloneable,但要求对象及所有字段可序列化;一行代码调用,适合DTO等纯数据对象,但性能较低且不复制static/transient字段。

Java 中的 Object.clone() 默认是浅拷贝,且需要类实现 Cloneable 接口并重写 clone() 方法,使用门槛高、易出错。而 Apache Commons Lang 的 SerializationUtils.clone() 提供了一种更简单、安全的深拷贝方式——基于序列化机制,无需修改原类定义(只要类可序列化)。
前提条件:确保目标类可序列化
要使用 SerializationUtils.clone(),被克隆的对象及其所有字段(包括嵌套对象)必须实现 java.io.Serializable 接口。否则会抛出 NotSerializableException。
- 基本类型、String、常见集合(如
ArrayList、HashMap)默认可序列化 - 自定义类需显式声明
implements Serializable,建议加上private static final long serialVersionUID = 1L; - 含不可序列化字段(如
Thread、Socket、或标记为transient的字段)时,这些字段在克隆后为null或默认值
引入依赖(Maven)
确保项目中已引入 Apache Commons Lang 3(推荐 3.12.0+):
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
基本用法:一行代码完成深拷贝
调用 SerializationUtils.clone() 即可,泛型支持自动类型推导:
立即学习“Java免费学习笔记(深入)”;
MyData original = new MyData("hello", new ArrayList<>(Arrays.asList(1, 2)));
MyData cloned = SerializationUtils.clone(original); // 深拷贝
此时修改 cloned.getList().add(3) 不会影响 original.getList(),验证了深拷贝效果。
- 方法内部通过将对象序列化为字节数组,再反序列化为新对象,天然实现深拷贝
- 返回对象与原对象不共享任何引用(除不可变对象如 String、Integer 等 JVM 缓存对象外)
- 原始对象无需实现
Cloneable,也不用重写clone()
注意事项与局限性
该方式虽便捷,但有几点必须注意:
- 性能开销较大:涉及 I/O 和反射,比浅拷贝或手动构造慢,不适合高频调用场景
-
静态字段和 transient 字段不会被复制:静态字段属于类,
transient字段被序列化机制跳过 - 无法处理含非序列化资源的对象:如打开的文件流、数据库连接等,克隆后可能失效或引发异常
- 要求类无无参构造器不影响克隆:反序列化不调用构造器,所以即使类只有带参构造器也能克隆(前提是可序列化)
不复杂但容易忽略:它不是万能替代,适合配置类、DTO、POJO 等纯数据对象的快速深拷贝;对性能敏感或含复杂状态的对象,建议用构造器、BeanUtils 或专用克隆库(如 Dozer、ModelMapper)。


















