大佬们好!我是LKJ_Coding,一枚初级马牛,正在努力在代码的丛林中找寻自己的方向。如果你也曾在调试中迷失,或是在文档中翻滚,那我们一定有许多共同话题可以聊!今天,我带着满满的代码“干货”来和大家分享,学不学无所谓,反正我先吐槽了!

前言

  在 Java 中,序列化是指将对象的状态转换为字节流的过程,以便将其保存到磁盘、通过网络发送或存储到数据库中。而反序列化是指将字节流转换回对象的过程。序列化和反序列化使得 Java 对象能够在不同的环境或不同的程序之间传输。

  本文将介绍序列化和反序列化的基本概念,如何使用 Serializable 接口实现对象的序列化,如何使用 ObjectInputStreamObjectOutputStream 进行对象的序列化与反序列化,并通过代码示例展示如何实现这些功能。

1. 序列化与反序列化的基本概念

1.1 序列化

序列化是将对象转换为字节流的过程。Java 中的序列化机制允许将对象的状态保存为字节流,并能够恢复这些对象的状态。序列化通常用于以下场景:

  • 将对象保存到文件系统。
  • 将对象发送到远程服务器。
  • 将对象存储在数据库中。

1.2 反序列化

反序列化是将字节流转换回对象的过程。通过反序列化,我们可以将从文件、网络等读取的字节流重新恢复为 Java 对象。

1.3 Java 的序列化机制

在 Java 中,要实现序列化,类必须实现 java.io.Serializable 接口。这个接口是一个标记接口,表示该类的对象可以被序列化和反序列化。需要注意的是,Serializable 接口没有任何方法,因此它的作用仅仅是作为一个标记,告诉 JVM 对象可以进行序列化。

2. 使用 Serializable 接口

2.1 让对象支持序列化

要让 Java 类支持序列化,只需让该类实现 Serializable 接口。实现该接口后,类的对象可以被序列化成字节流,并可以通过反序列化恢复。

2.1.1 示例:实现 Serializable 接口

import java.io.Serializable;public class Person implements Serializable {private static final long serialVersionUID = 1L;  // 推荐声明 serialVersionUIDprivate String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + '}';}
}

在这个例子中:

  • Person 类实现了 Serializable 接口,表示该类的对象可以被序列化。
  • serialVersionUID 是一个版本控制号,用于确保序列化和反序列化的兼容性。如果类的版本发生变化,可以修改 serialVersionUID,确保反序列化时的兼容性。

2.2 序列化对象

ObjectOutputStream 类用于将对象写入输出流,从而实现对象的序列化。

2.2.1 示例:序列化对象

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class SerializationExample {public static void main(String[] args) {Person person = new Person("Alice", 30);try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {oos.writeObject(person);  // 序列化对象System.out.println("Object serialized successfully.");} catch (IOException e) {e.printStackTrace();}}
}

在这个示例中:

  • 使用 ObjectOutputStreamperson 对象序列化到 person.ser 文件中。
  • writeObject() 方法将对象写入输出流。

3. 使用 ObjectInputStreamObjectOutputStream 进行对象的序列化与反序列化

3.1 反序列化对象

ObjectInputStream 类用于从输入流中读取对象,从而实现对象的反序列化。反序列化的过程是将字节流转换回原始的 Java 对象。

3.1.1 示例:反序列化对象

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class DeserializationExample {public static void main(String[] args) {try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {Person person = (Person) ois.readObject();  // 反序列化对象System.out.println("Deserialized object: " + person);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

在这个示例中:

  • 使用 ObjectInputStreamperson.ser 文件中读取字节流,并通过 readObject() 方法将字节流转换回 Person 对象。
  • 通过反序列化恢复了 Person 对象,并打印出其信息。

3.2 完整的序列化和反序列化示例

以下是一个完整的示例,展示如何序列化和反序列化对象:

import java.io.*;public class SerializationExample {// Person 类实现 Serializable 接口public static class Person implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + '}';}}public static void main(String[] args) {// 序列化Person person = new Person("Alice", 30);try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {oos.writeObject(person);System.out.println("Object serialized successfully.");} catch (IOException e) {e.printStackTrace();}// 反序列化try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {Person deserializedPerson = (Person) ois.readObject();System.out.println("Deserialized object: " + deserializedPerson);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

3.3 处理序列化异常

在 Java 中,序列化的类需要实现 Serializable 接口。如果尝试序列化一个没有实现该接口的类,会抛出 java.io.NotSerializableException 异常。

3.3.1 示例:序列化异常

import java.io.*;public class SerializationErrorExample {public static void main(String[] args) {try {// 尝试序列化一个没有实现 Serializable 接口的类ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("error.ser"));oos.writeObject(new NonSerializableClass());  // 该类没有实现 Serializableoos.close();} catch (IOException e) {System.out.println("Serialization failed: " + e.getMessage());}}
}class NonSerializableClass {// 该类没有实现 Serializable 接口
}

在这个示例中,NonSerializableClass 没有实现 Serializable 接口,因此会抛出 NotSerializableException 异常。

4. 总结

Java 提供了强大的序列化和反序列化机制,允许将对象转换为字节流并保存或传输,之后可以通过反序列化恢复对象。核心步骤如下:

  • 实现 Serializable 接口:要序列化一个对象,类必须实现 Serializable 接口。
  • 使用 ObjectOutputStreamObjectInputStreamObjectOutputStream 用于序列化对象,ObjectInputStream 用于反序列化对象。
  • 处理序列化异常:如果类没有实现 Serializable 接口,或者对象中有不支持序列化的字段,将会抛出异常。

通过这些机制,Java 使得对象在网络传输、文件存储等场景下的持久化变得非常方便。

好啦,废话不多说,今天的分享就到这里!如果你觉得我这“初级马牛”还挺有趣,那就请给我点个赞、留个言、再三连击三连哦!让我们一起“成精”吧!下次见,不见不散!