在 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

如果你使用的是 Jackson2JsonRedisSerializerGenericJackson2JsonRedisSerializer,它们基于 Jackson 进行 JSON 序列化,不依赖 Java 原生的序列化机制,因此 User 类不需要实现 Serializable

示例:

public class User {
    private String name;
    private int age;

    // 构造方法、Getter、Setter
}

这种情况下,User 可以被 Jackson2JsonRedisSerializer 正常序列化和反序列化,因为 Jackson 只要求:

  • 必须有一个无参构造方法(否则反序列化会失败)。

  • 字段必须有 getter 和 setter(或者使用 @JsonProperty 注解)。


🔴 什么时候需要实现 Serializable

  1. 如果你仍然可能使用 JDK 自带的序列化(如 JdkSerializationRedisSerializer

    • JdkSerializationRedisSerializer 依赖 Java 的 Serializable 机制,必须让对象实现 Serializable,否则会报错:

java.io.NotSerializableException: User
  • 但由于 JdkSerializationRedisSerializer 存储的是 二进制数据,Redis 里的数据不可读,因此不推荐使用。

  1. 你的对象需要在不同的存储方式之间切换

    • 如果你的对象可能不仅仅被 Redis 使用,还可能被 Java 的 ObjectOutputStream 或者其他序列化框架(如 KafkaRocketMQDubbo)传输,最好实现 Serializable 以确保兼容性

  2. 你的团队有“统一实现 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. 总结

序列化方式

是否需要 Serializable

说明

JdkSerializationRedisSerializer

✅ 需要

依赖 Java 原生序列化,必须实现 Serializable

Jackson2JsonRedisSerializer

❌ 不需要

仅基于 JSON 序列化,不依赖 Serializable

GenericJackson2JsonRedisSerializer

❌ 不需要

自动存储类型信息,不需要 Serializable

Kafka / Dubbo / RocketMQ 等

✅ 推荐

可能涉及 JDK 序列化,建议实现

🚀 最佳实践如果 Redis 只存 JSON,不用 JDK 序列化,就不需要 Serializable。如果你的对象可能被其他组件(如 MQ、RPC 框架)使用,建议实现 Serializable,以确保兼容性!