Java中的序列化和反序列化是什么?

在 Java 中,序列化(Serialization)和反序列化(Deserialization)是对象持久化和恢复的关键技术。它们用于将对象的状态转换为可以存储或传输的格式,并在需要时将其恢复为原始对象。以下是详细介绍:

序列化(Serialization)

定义

  • 序列化 是将 Java 对象的状态转换为字节流的过程。这种字节流可以存储在文件中、发送到网络上,或在其他地方保存。

用途

  • 持久化:将对象状态保存到文件或数据库中,以便将来恢复。
  • 传输:在网络上发送对象,允许不同的 Java 应用程序或系统之间交换数据。

实现

  • 对象必须实现 Serializable 接口,这是一个标记接口(没有方法)。
  • 序列化过程由 ObjectOutputStream 完成,将对象写入流中。

示例

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

class Person implements Serializable {
    private static final long serialVersionUID = 1L; // 序列化版本号
    String name;
    int age;

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

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

        try (FileOutputStream fileOut = new FileOutputStream("person.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(person);
            System.out.println("Serialized data is saved in person.ser");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们将 Person 对象序列化并保存到文件 person.ser 中。

反序列化(Deserialization)

定义

  • 反序列化 是将字节流转换回 Java 对象的过程。这允许我们从保存的字节流中恢复对象的状态。

用途

  • 恢复持久化对象的状态,从文件或网络流中读取对象数据。
  • 实现对象在不同 JVM 或进程之间的交换。

实现

  • 反序列化过程由 ObjectInputStream 完成,从流中读取对象并恢复其状态。

示例

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;

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

public class DeserializationExample {
    public static void main(String[] args) {
        Person person = null;

        try (FileInputStream fileIn = new FileInputStream("person.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            person = (Person) in.readObject();
            System.out.println("Deserialized Person:");
            System.out.println("Name: " + person.name);
            System.out.println("Age: " + person.age);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们从文件 person.ser 中反序列化 Person 对象,并输出其内容。

重要概念

  1. 序列化版本号(serialVersionUID)

    • serialVersionUID 是一个唯一的标识符,用于确保序列化和反序列化过程的兼容性。如果类发生变化但 serialVersionUID 保持不变,序列化和反序列化仍然可以成功进行。建议显式声明 serialVersionUID
  2. Transient 关键字

    • 使用 transient 修饰的字段不会被序列化。这意味着,序列化和反序列化时这些字段的值会被忽略,恢复后的对象将不包含这些字段的值。

    示例

    class Person implements Serializable {
        private static final long serialVersionUID = 1L;
        String name;
        int age;
        transient String password; // 不会被序列化
    
        Person(String name, int age, String password) {
            this.name = name;
            this.age = age;
            this.password = password;
        }
    }
    

  3. 自定义序列化

    • 可以实现 writeObjectreadObject 方法来定制序列化和反序列化的过程。例如,可以在序列化过程中添加额外的验证或转换逻辑。

    示例

    class Person implements Serializable {
        private static final long serialVersionUID = 1L;
        String name;
        int age;
    
        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws IOException {
            out.defaultWriteObject();
            out.writeInt(age); // 自定义序列化过程
        }
    
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            age = in.readInt(); // 自定义反序列化过程
        }
    }
    

总结

  • 序列化 是将 Java 对象转换为字节流以便存储或传输。
  • 反序列化 是将字节流转换回 Java 对象以恢复其状态。
  • 序列化和反序列化使得对象持久化和跨进程、跨网络的数据交换成为可能。
  • serialVersionUIDtransient 关键字和自定义序列化方法是序列化过程中的重要概念和工具。
  • 21
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值