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();
}
}