什么是序列化?什么是反序列化?

什么是序列化(Serialization)和反序列化(Deserialization)?

在 Java 中,序列化(Serialization)反序列化(Deserialization) 是用于 对象与字节流之间转换 的机制,通常用于在 网络传输、文件存储、缓存 等场景中。


1. 什么是序列化(Serialization)?

序列化 是指将 Java 对象转换为字节流(byte stream) 的过程,以便:

  • 存储 到磁盘文件或数据库中。
  • 传输 通过网络发送给其他系统或应用程序。
  • 缓存 例如 Redis 等内存数据库。

序列化的核心作用:

  • 持久化: 保存对象的状态到硬盘(如文件或数据库)。
  • 网络传输: 通过字节流形式发送对象。
  • 缓存: 快速读取对象状态。

序列化示例:
import java.io.*;

class Person implements Serializable {  // 必须实现 Serializable 接口
    private static final long serialVersionUID = 1L;  // 建议添加 serialVersionUID
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

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("序列化成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出:

序列化成功!

解释:

  • person.ser 文件中保存的是 Person 对象的 字节流形式
  • Serializable 是一个 标记接口(没有方法),用于标识可序列化的类。

2. 什么是反序列化(Deserialization)?

反序列化 是指将 字节流恢复为 Java 对象 的过程,用于:

  • 读取存储的对象(从文件、数据库等)。
  • 接收网络传输的对象(如 RPC 调用)。
  • 恢复缓存中的对象(如从 Redis 读取)。

反序列化的核心作用:

  • 恢复对象状态: 从字节流还原为 Java 对象。
  • 数据传输: 接收和解析网络上的对象数据。

反序列化示例:
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("反序列化成功!");
            System.out.println("姓名: " + person.name + ", 年龄: " + person.age);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

反序列化成功!
姓名: Alice, 年龄: 30

解释:

  • ObjectInputStream 读取 person.ser 文件中的 字节流,并将其还原为 Person 对象。
  • 反序列化要求类必须有 无参构造方法(即使不显式定义,Java 默认提供)。

3. 序列化与反序列化的关键点:

关键点 序列化(Serialization) 反序列化(Deserialization)
作用 对象转字节流 字节流转对象
使用的流 ObjectOutputStream ObjectInputStream
标记接口 Serializable Serializable(要求类可序列化)
必须有 serialVersionUID 吗? 建议有,用于版本控制 同上
无法序列化的修饰符 transient(忽略字段),static(类级别,无需序列化) 同上

4. 序列化和反序列化中常见问题:

  1. 没有实现 Serializable 接口:

    • 会抛出 NotSerializableException 异常。
  2. serialVersionUID 不一致:

    • 反序列化时会抛出 InvalidClassException 异常。
    • 解决办法: 明确指定 serialVersionUID,如:
      private static final long serialVersionUID = 1L;
      
  3. transient 关键字:

    • 标记的字段不会被序列化。例如:
      transient int password;  // 不会被序列化
      

5. 总结:一句话理解序列化与反序列化

  • 序列化: 将对象转化为字节流,便于 存储和传输
  • 反序列化: 将字节流转化回对象,便于 读取和使用

你可能感兴趣的:(java,八股,序列化,反序列化)