在 Java 中,泛型(Generics)本身并不会直接影响序列化的机制,因为 Java 的序列化是基于 对象的实际运行时类型(字节码层面) 进行的,而泛型在编译后会被类型擦除(Type Erasure)。但在“使用泛型写可序列化类/结构”时,有一些关键点、坑和正确用法需要注意。
下面从 原理 → 常见用法 → 注意事项 → 示例 四部分说明。
class Box<T> implements Serializable {
T value;
}
编译后等价于(逻辑上):
class Box implements Serializable {
Object value;
}
✅ 序列化时:
value 的 实际对象T 是什么类型只要:
SerializableSerializable就可以正常序列化。
import java.io.*;
public class Box<T> implements Serializable {
private T value;
public Box(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
使用:
Box<String> box = new Box<>("hello");
✅ 要求:
String 是可序列化的Box 是可序列化的// 序列化
try (ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("box.dat"))) {
oos.writeObject(box);
}
// 反序列化
try (ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("box.dat"))) {
Box<String> box2 = (Box<String>) ois.readObject();
}
⚠️ 注意:
Box<String> box2 = (Box<String>) ois.readObject();
<String> 只是编译期检查Stringclass Holder<T> implements Serializable {
T data;
}
Holder<Thread> h = new Holder<>(new Thread());
❌ 会抛:
NotSerializableException: java.lang.Thread
✅ 解决:
T 的实际类型可序列化transientBox box = (Box) ois.readObject();
Object v = box.getValue(); // 只知道是 Object
Java 无法在运行时恢复泛型类型。
T[] array; // ❌ 不能直接 new T[]
序列化时:
✅ 正确写法:
@SuppressWarnings("unchecked")
T[] array = (T[]) new Object[10];
class TypeToken<T> {
private final Type type;
protected TypeToken() {
type = getClass().getGenericSuperclass();
}
public Type getType() {
return type;
}
}
✅ 常用于:
class Box<T> implements Serializable {
private T value;
private Class<T> type;
public Box(T value, Class<T> type) {
this.value = value;
this.type = type;
}
}
Java 序列化不关心泛型,只关心“运行时的对象是否可序列化”。
SerializableSerializable如果你有具体场景(比如 RPC / Redis / JSON / 泛型集合序列化),我可以给你更针对性的写法。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。