在 Java 中,Serializable
是一个 标记接口(Marker Interface),用于指示某个类的对象可以被 序列化 和 反序列化。
1. 作用
序列化(Serialization):将对象转换为字节流,以便存储到文件、数据库,或通过网络传输。
反序列化(Deserialization):将字节流恢复为原始对象。
序列化和反序列化
public class SerializationDemo {
public static void main(String[] args) {
Person person = new Person("张", 22);
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person);
System.out.println("对象已序列化!");
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println("反序列化后的对象: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
1. Serializable
在 JSON 序列化中的作用
✅ 什么时候可以不实现 Serializable
?
如果你使用的是 Jackson2JsonRedisSerializer 或 GenericJackson2JsonRedisSerializer,它们基于 Jackson 进行 JSON 序列化,不依赖 Java 原生的序列化机制,因此 User
类不需要实现 Serializable
。
示例:
public class User {
private String name;
private int age;
// 构造方法、Getter、Setter
}
这种情况下,User
可以被 Jackson2JsonRedisSerializer
正常序列化和反序列化,因为 Jackson 只要求:
必须有一个无参构造方法(否则反序列化会失败)。
字段必须有 getter 和 setter(或者使用
@JsonProperty
注解)。
🔴 什么时候需要实现 Serializable
?
如果你仍然可能使用 JDK 自带的序列化(如
JdkSerializationRedisSerializer
)JdkSerializationRedisSerializer
依赖 Java 的Serializable
机制,必须让对象实现Serializable
,否则会报错:
java.io.NotSerializableException: User
但由于
JdkSerializationRedisSerializer
存储的是 二进制数据,Redis 里的数据不可读,因此不推荐使用。
你的对象需要在不同的存储方式之间切换
如果你的对象可能不仅仅被 Redis 使用,还可能被 Java 的
ObjectOutputStream
或者其他序列化框架(如Kafka
、RocketMQ
、Dubbo
)传输,最好实现Serializable
以确保兼容性。
你的团队有“统一实现
Serializable
”的编码规范一些团队习惯于让所有数据类实现
Serializable
,以确保不会因为未来可能的JdkSerializationRedisSerializer
需求而报错。
2. 是否有性能影响?
不实现
Serializable
时,Jackson 只使用 JSON 方式序列化,不涉及writeObject
/readObject
方法,性能更好。实现
Serializable
后,虽然不会影响 Jackson 的 JSON 序列化,但如果意外使用JdkSerializationRedisSerializer
,可能会增加额外的开销。
3. 最佳实践
✅ 推荐:
只使用 JSON 序列化时,
User
类不需要实现Serializable
,只需保证有无参构造器和getter/setter
方法。如果你的系统可能用到 JDK 序列化或分布式传输(如 Kafka、Dubbo),建议实现
Serializable
,以保证兼容性。
示例:
public class User implements Serializable { // 可选的 Serializable
private static final long serialVersionUID = 1L; // 推荐手动定义 serialVersionUID
private String name;
private int age;
// 构造方法、Getter、Setter
}
注意:如果你决定实现
Serializable
,最好手动定义serialVersionUID
,避免类修改后反序列化失败的问题。
4. 总结
🚀 最佳实践:如果 Redis 只存 JSON,不用 JDK 序列化,就不需要 Serializable
。如果你的对象可能被其他组件(如 MQ、RPC 框架)使用,建议实现 Serializable
,以确保兼容性!