14.0、Java_IO流 - 对象流、序列化与反序列化
**14.0 Java IO 流 - 对象流、序列化与反序列化**
在 Java 中,IO 流是用于读取和写入数据的基本类。其中,对象流(Object Stream)是一个非常重要的概念,它允许我们将 Java 对象转换为字节流,从而实现对这些对象的序列化和反序列化。
**什么是序列化和反序列化?**
序列化是指将一个 Java 对象转换为字节流的过程,而反序列化则是指将字节流转换回原来的 Java 对象。序列化和反序列化的主要目的是为了在网络传输或存储中保存和恢复 Java 对象。
**Java 中的对象流**
Java 提供了一个名为 `ObjectOutputStream` 的类,它负责将 Java 对象转换为字节流,从而实现对这些对象的序列化。相反,`ObjectInputStream` 类则用于将字节流转换回原来的 Java 对象。
**序列化过程**
序列化过程涉及以下几个步骤:
1. **写入标记**:首先,序列化器会写入一个标记,这个标记表示序列化开始。
2. **写入对象的类型**:接着,序列化器会写入被序列化的 Java 对象的类型信息。
3. **写入对象的属性**:然后,序列化器会根据对象的类型和属性顺序写入每个属性的值。
4. **写入结束标记**:最后,序列化器会写入一个结束标记,这个标记表示序列化结束。
**反序列化过程**
反序列化过程涉及以下几个步骤:
1. **读取标记**:首先,反序列化器会读取一个标记,这个标记表示反序列化开始。
2. **读取对象的类型**:接着,反序列化器会读取被反序列化的 Java 对象的类型信息。
3. **读取对象的属性**:然后,反序列化器会根据对象的类型和属性顺序读取每个属性的值。
4. **读取结束标记**:最后,反序列化器会读取一个结束标记,这个标记表示反序列化结束。
**示例代码**
以下是使用 `ObjectOutputStream` 和 `ObjectInputStream` 类进行序列化和反序列化的示例代码:
javaimport java.io.*; import java.util.*; public class SerializationExample { public static void main(String[] args) throws IOException, ClassNotFoundException { // 创建一个 Person 对象 Person person = new Person("John",30); // 使用 ObjectOutputStream 进行序列化 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) { oos.writeObject(person); } // 使用 ObjectInputStream 进行反序列化 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) { Person deserializedPerson = (Person) ois.readObject(); System.out.println(deserializedPerson.getName()); // John System.out.println(deserializedPerson.getAge()); //30 } } } class Person implements Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
在这个示例中,我们首先创建一个 `Person` 对象,然后使用 `ObjectOutputStream` 进行序列化。接着,我们使用 `ObjectInputStream` 进行反序列化,并打印出反序列化后的 `Person` 对象的属性值。
**注意事项**
在进行序列化和反序列化时,需要注意以下几点:
* **实现 Serializable 接口**:被序列化的 Java 对象必须实现 `Serializable` 接口。
* **定义 serialVersionUID**:每个类都应该定义一个 `serialVersionUID`,它用于标识该类的序列化版本。
* **避免循环引用**:序列化和反序列化过程中,不要出现循环引用,这可能会导致死锁或其他问题。
通过遵循这些注意事项和示例代码,你就可以轻松地使用 Java 的对象流进行序列化和反序列化。