序列化和反序列化

Beiyu 发布于 5 天前 21 次阅读


概念:

java序列化:是将对象的状态信息转化为可以存储或者传输的形式的过程(把对象转换成有序字节流)。在序列化的过程中还能递归保存对象引用的每个对象的数据(深复制)。
反序列化:将有序字节流还原成与之前完全相等的对象,这个相反的过程又称为反序列化。

场景描述:

  • 当需要将对象的状态保存到文件或数据库中时。(对象都存在于JVM中的堆(heap)内存中,JVM停止对象也会消失)
  • 在分布式系统中,不同进程或不同机器之间的通信经常使用到传输对象。
  • 通过序列化和反序列化可以实现对象的深拷贝。

应用场景:

  • 用户登录信息、用户配置文件、游戏存档等。
  • 在微服务架构中,服务A需要将一个用户对象发送给服务B进行处理。
  • 复制一个包含多个嵌套对象的对象。
  • 需要频繁查询数据库的操做,把数据缓存在redis。java中的对象可以序列化后保存到redis中以String类型存储。

注意事项:

  • 序列化后的字节流可能包含敏感信息,因此在传输和存储时需要注意加密和安全措施。
  • 序列化涉及到的性能开销较大,而Java标准序列化机制性能较差,可以使用其他序列化框架,如Kryo、Protobuf、Jackson等。这些框架通过优化序列化算法、减少元数据等方式提高了性能。
  • 在性能敏感的应用中需要谨慎使用。

示例:

定义一个可序列化的类
需要实现SerializableSerializable是一个标记接口表示该类的对象可以被序列化。

import java.io.Serializable;
import lombok.Data;
@Data
public class Person implements Serializable {
    private static final long serialVersionUID = 1L; // 版本号,用于序列化兼容性

    private String name;
    private int age;
}

序列化对象到文件

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerializeExample {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            oos.writeObject(person); // 序列化对象并写入文件
            System.out.println("对象已成功序列化到文件 person.ser");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

从文件反序列化对象

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeserializeExample {
    public static void main(String[] args) {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person person = (Person) ois.readObject(); // 从文件中读取并反序列化对象
            System.out.println("反序列化后的对象: " + person);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

序列化和反序列化可能会抛出IOExceptionClassNotFoundException等异常,需要进行适当的异常处理。

此作者没有提供个人介绍
最后更新于 2025-04-17