Java 中的序列化与反序列化是在对象和字节流之间进行转换的过程。简单来说,序列化就是将对象转换为字节流的过程,而反序列化则是将字节流转换为对象的过程。这种转换可以使得对象在网络中进行传输,或者在文件中进行存储。
为什么需要序列化与反序列化呢?因为在网络传输和文件存储时,只能传输和存储二进制数据,无法直接传输和存储 Java 对象。所以,我们需要将对象转换为字节流进行传输或存储,然后再将字节流转换回对象进行使用。
在 Java 中,我们可以通过实现 Serializable 接口来进行序列化。Serializable 是一个标记接口,不包含任何方法定义。当一个类实现了 Serializable 接口时,表明该类的对象可以被序列化。在序列化过程中,对象的所有非静态成员变量都会被转换为字节流,并且包括对象的类型信息。
让我们通过一个例子来看看如何进行序列化与反序列化。假设我们有一个名为 Student 的类,其中包含学生的姓名和年龄两个成员变量:
```java
import java.io.*;
public class Student implements Serializable {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Student student = new Student("Tom", 20);
// 序列化对象
try {
FileOutputStream fileOut = new FileOutputStream("student.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(student);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in student.ser");
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化对象
try {
FileInputStream fileIn = new FileInputStream("student.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Student deserializedStudent = (Student) in.readObject();
in.close();
fileIn.close();
System.out.println("Deserialized data: ");
System.out.println("Name: " + deserializedStudent.name);
System.out.println("Age: " + deserializedStudent.age);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
```
在上面的代码中,我们首先创建了一个 Student 对象,并将其序列化到一个名为 student.ser 的文件中。然后我们再从该文件中反序列化出一个新的 Student 对象,并打印出其中的姓名和年龄信息。
需要注意的是,被序列化的类必须实现 Serializable 接口,否则会抛出 NotSerializableException 异常。另外,如果类中有某些成员变量不希望被序列化,可以使用 transient 关键字进行标记,表示该变量在序列化过程中不被考虑。
通过序列化与反序列化,我们可以方便地在网络中传输对象,或者将对象保存到文件中。这在分布式系统、缓存管理和数据持久化等场景中非常有用。当然,在实际的开发中,我们也需要注意序列化版本号的问题,以及安全性和性能方面的考虑。
综上所述,Java 中的序列化与反序列化是一种将对象转换为字节流进行传输和存储的技术。通过实现 Serializable 接口,我们可以将对象序列化为字节流,并在需要时反序列化为对象。这种技术在网络传输和文件存储中非常实用,为我们处理对象的传输和存储问题提供了便利。