Java对象序列化及反序列化教程

1. 什么是对象序列化?

在Java编程语言中,对象序列化是指将一个对象转换为字节序列的过程。换句话说,对象序列化是指将一个对象的状态保存为一系列字节,以便在以后可以将这些字节恢复为原始对象的过程。对象序列化在网络通信中起着重要的作用,它可以用于在网络上传输对象,或者将对象保存到磁盘上。

对象序列化采用的是Java提供的Serializable接口,该接口是标记接口,不包含任何方法。通过实现Serializable接口,可以告诉Java虚拟机该类的对象可以被序列化。不想让某些字段参与序列化的就加@transient注解。

2. 什么是反序列化?

反序列化是指将字节序列恢复为对象的过程。在Java中,反序列化将字节序列转换为对象的状态,并创建一个与原始对象具有相同状态的新对象。

3. 实现对象序列化需要做哪些工作?

要实现对象序列化,需要进行以下工作:

a. 实现Serializable接口

要使一个类可以被序列化,必须实现Serializable接口。该接口没有任何方法,只是作为一个标记,告诉Java虚拟机该类的对象可以被序列化。

以下是一个实现Serializable接口的示例:

import java.io.Serializable;

public class MyClass implements Serializable {
    private String name;
    private int age;

    // 省略构造方法和其他方法

    // 省略getter和setter方法
}

b. 为每个可序列化的字段添加序列化ID

每个可序列化的字段都需要添加一个序列化ID,以便在反序列化时可以检查传入的字节序列是否与类的定义兼容。序列化ID可以通过手动指定或自动生成。

以下是手动指定序列化ID的示例:

private static final long serialVersionUID = 123456789L;

c. 实现序列化方法

在可序列化的类中,需要实现writeObject()和readObject()方法。这些方法用于定义对象的序列化和反序列化过程。

以下是实现序列化方法的示例:

private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    out.writeObject(name);
    out.writeInt(age);
}

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
    name = (String) in.readObject();
    age = in.readInt();
}

d. 使用ObjectOutputStream进行序列化

要将对象序列化为字节序列,可以使用ObjectOutputStream类。它提供了一种将对象写入输出流的方法。

以下是将对象序列化为字节序列的示例:

MyClass obj = new MyClass();
// 初始化obj的属性

try {
    FileOutputStream fileOut = new FileOutputStream("myclass.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(obj);
    out.close();
    fileOut.close();
} catch (IOException e) {
    e.printStackTrace();
}

e. 使用ObjectInputStream进行反序列化

要将字节序列反序列化为对象,可以使用ObjectInputStream类。它提供了一种从输入流中读取对象的方法。

以下是从字节序列反序列化为对象的示例:

try {
    FileInputStream fileIn = new FileInputStream("myclass.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    MyClass obj = (MyClass) in.readObject();
    in.close();
    fileIn.close();
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

4. 示例代码和测试代码

下面是一个完整的示例代码,演示了对象序列化和反序列化的过程,并对序列化后的对象进行了输出打印:

import java.io.*;

public class SerializationExample {
    public static void main(String[] args) {
        MyClass obj = new MyClass("John Doe", 25);

        // 序列化对象
        try {
            FileOutputStream fileOut = new FileOutputStream("myclass.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(obj);
            out.close();
            fileOut.close();
            System.out.println("对象已序列化到文件 myclass.ser");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化对象
        try {
            FileInputStream fileIn = new FileInputStream("myclass.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            MyClass deserializedObj = (MyClass) in.readObject();
            in.close();
            fileIn.close();
            System.out.println("从文件 myclass.ser 反序列化对象成功");
            System.out.println("姓名:" + deserializedObj.getName());
            System.out.println("年龄:" + deserializedObj.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class MyClass implements Serializable {
    private static final long serialVersionUID = 123456789L;

    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        out.writeObject(name);
        out.writeInt(age);
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        age = in.readInt();
    }
}
正文到此结束
评论插件初始化中...
Loading...