序列化能实现深拷贝,因为反序列化会重建一个全新对象,其所有可序列化的引用类型字段也被递归重建,确保对象图中每个对象均为独立副本,修改副本不影响原对象。

在Java继承体系下,通过序列化和反序列化实现深拷贝,核心前提是:所有参与继承链的类(包括父类、中间类、子类)都必须实现 Serializable 接口,且不能有不可序列化的成员(如非静态非瞬态的线程、IO流、Socket等),否则会抛出 NotSerializableException。
为什么序列化能实现深拷贝
序列化是将对象状态转换为字节流的过程,反序列化是从字节流重建一个**全新对象**的过程。这个新对象与原对象内存地址不同,且其所有引用类型的字段(只要可序列化)也会被递归重建——这天然满足深拷贝语义:对象图中每个对象都是独立副本,修改副本不会影响原对象。
基础实现步骤(含继承支持)
以下是一个通用工具方法,适用于任意可序列化继承结构:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
public static <T extends Serializable> T deepClone(T obj) {
if (obj == null) return null;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)) {
oos.writeObject(obj);
return (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("Deep clone failed", e);
}
}
- 父类、子类均需显式实现
Serializable(推荐加上private static final long serialVersionUID避免版本问题) - 若某字段不希望被拷贝(如缓存、连接句柄),用
transient修饰,它会被跳过序列化 - 若某字段不可序列化但又必须存在,需在类中自定义
writeObject/readObject方法手动处理
继承场景下的注意事项
当存在多层继承(如 A ← B ← C)时:
立即学习“Java免费学习笔记(深入)”;
- 只要最顶层父类(A)实现了
Serializable,且中间类(B)、子类(C)未声明为final或阻止序列化,整个链就可序列化 - 如果某个父类**没有实现
Serializable**,那么该父类的字段在反序列化时会通过其无参构造器初始化(即调用默认值),不会复制原始值——此时不是真正的深拷贝,需手动处理或改用其他方案(如克隆构造器、第三方库) - 含有
static字段的类,其值不会被序列化(静态变量属于类,不属于对象实例),所以不影响拷贝结果
替代方案对比(简要)
序列化方式简单但有开销(IO、反射、字节流)且受限于可序列化性。其他常见深拷贝方式包括:
- 构造器注入:子类提供接收父类对象的构造器,在内部逐字段复制(需父类提供访问接口或暴露字段)
-
Apache Commons Lang 的
SerializationUtils.clone():本质仍是序列化封装,更简洁但依赖相同约束 - JSON 序列化(如 Jackson/Gson):适合 POJO,但要求无循环引用、无特殊类型(如 Date 需配置序列化器),且性能通常低于原生序列化

















