Java序列化和反序列化:玩转对象的“变形金刚”能力!

《Java零基础教学》是一套深入浅出的 Java 编程入门教程。全套教程从Java基础语法开始,适合初学者快速入门,同时也从实例的角度进行了深入浅出的讲解,让初学者能够更好地理解Java编程思想和应用。

本教程内容包括数据类型与运算、流程控制、数组、函数、面向对象基础、字符串、集合、异常处理、IO 流及多线程等 Java 编程基础知识,并提供丰富的实例和练习,帮助读者巩固所学知识。本教程不仅适合初学者学习,也适合已经掌握一定 Java 基础的读者进行查漏补缺。

前言

在 Java 开发中,我们经常需要将一个对象转换成字节数组或字符串进行传输和存储。Java 序列化 (Serialization) 和反序列化 (Deserialization) 是实现这一目的的重要手段。本文将介绍 Java 序列化和反序列化的基本概念和实现方法,并通过示例程序演示它们的使用。

摘要

本文首先介绍了 Java 序列化和反序列化的基本概念,包括其作用、原理和注意事项。接着,我们讲解了如何在 Java 中实现序列化和反序列化操作,包括使用 Serializable 接口和 Externalizable 接口实现对象的序列化和反序列化。最后,我们通过示例程序演示了 Java 序列化和反序列化的使用方法,包括对象的序列化和反序列化、文件的序列化和反序列化等。

内容

Java 序列化和反序列化是 Java 编程中常用的一种数据转换方式,它们的主要作用是将 Java 对象转换成字节数组或字符串进行传输和存储。Java 序列化和反序列化的具体实现基于 Java 中的 Serializable 接口和 Externalizable 接口。

Serializable 接口

Serializable 接口是 Java 中的一个标记接口,用于标识一个类的实例可以被序列化。一个类只有实现了 Serializable 接口,才能被序列化为字节数组或字符串。

java 复制代码
public interface Serializable {

}

在实现 Serializable 接口的类中,可以定义一个名为 serialVersionUID 的静态常量,用于标识该类的版本号。当反序列化时,Java 虚拟机会根据类的版本号来检查反序列化对象与当前类是否兼容。

java 复制代码
public class User implements Serializable {
    private String name;
    private int age;
    private static final long serialVersionUID = 1L; // 版本号
    // ...
}

Externalizable 接口

Externalizable 接口继承了 Serializable 接口,它定义了两个方法:writeExternal() 和 readExternal(),用于手动控制对象的序列化和反序列化过程。实现 Externalizable 接口需要重写这两个方法。

java 复制代码
public interface Externalizable extends java.io.Serializable {
    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

序列化对象

序列化一个 Java 对象的过程需要进行以下操作:

  1. 创建 ObjectOutputStream 对象;
  2. 调用 ObjectOutputStream 的 writeObject() 方法将对象序列化成字节数组或字符串;
  3. 关闭 ObjectOutputStream 对象。
java 复制代码
public class SerializableTest {
    public static void main(String[] args) throws IOException {
        User user = new User("Tom", 20);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.dat"));
        out.writeObject(user);
        out.close();
    }
}

在上述代码中,我们创建了一个 User 对象并将其序列化成一个文件 user.dat。可以通过以下代码反序列化该文件:

java 复制代码
public class DeserializableTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.dat"));
        User user = (User) in.readObject();
        in.close();
    }
}

序列化文件

Java 序列化还可以用于文件的序列化和反序列化。例如,我们可以将一个 Java 对象序列化成文件,然后在需要的时候将其反序列化出来,而不是每次重新构造对象。代码如下:

java 复制代码
public class SerializableFileTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        User user = new User("Tom", 20);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.dat"));
        out.writeObject(user);
        out.close();

        ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.dat"));
        User user2 = (User) in.readObject();
        in.close();
    }
}

注意事项

在 Java 序列化和反序列化过程中,需要注意以下事项:

  1. 被序列化的对象必须实现 Serializable 接口或 Externalizable 接口;
  2. 被序列化的对象的所有实例变量必须是可序列化的。如果一个对象包含了一个不可序列化的实例变量,则序列化操作会失败;
  3. 被序列化的对象中的静态变量不会被序列化;
  4. 被序列化的对象中的 transient 关键字修饰的变量不会被序列化。

代码方法介绍

  • ObjectOutputStream

    • 构造方法

      java 复制代码
      public ObjectOutputStream(OutputStream out) throws IOException
    • 方法

      java 复制代码
      public final void writeObject(Object obj) throws IOException
  • ObjectInputStream

    • 构造方法

      java 复制代码
      public ObjectInputStream(InputStream in) throws IOException
    • 方法

      java 复制代码
      public final Object readObject() throws IOException, ClassNotFoundException

测试用例

我们可以通过以下测试用例来验证 Java 序列化和反序列化的正确性:

java 复制代码
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        User user = new User("Tom", 20);

        // 将 User 对象序列化成字节数组
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(bos);
        out.writeObject(user);
        byte[] bytes = bos.toByteArray();

        // 将字节数组反序列化成 User 对象
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream in = new ObjectInputStream(bis);
        User user2 = (User) in.readObject();

        // 验证两个 User 对象是否相同
        System.out.println(user.equals(user2)); // true
    }

测试用例执行如下:

全文小结

本文介绍了 Java 序列化和反序列化的基本概念和实现方法,包括使用 Serializable 接口和 Externalizable 接口实现对象的序列化和反序列化。我们还通过示例程序演示了 Java 序列化和反序列化的使用方法,包括对象的序列化和反序列化、文件的序列化和反序列化等。在使用 Java 序列化和反序列化时,我们需要注意被序列化的对象的实现方式和实例变量的可序列化性,以确保程序正常运行。

最后

大家如果觉得看了本文有帮助的话,麻烦给个三连(点赞、分享、转发)支持一下哈。

相关推荐
浩瀚星辰2024几秒前
C++树状数组详解
java·数据结构·算法
h0l10w24 分钟前
【Java】MongoDB
java·开发语言·mongodb
南雨北斗24 分钟前
VSCODE进行代码格式化的方法
后端
深栈解码26 分钟前
第一章:认识JVM:跨平台的引擎与生态基石
java·后端
用户403159863966330 分钟前
简易二进制编辑器
java·算法
bin915333 分钟前
飞算 JavaAI:开启 Java 开发新时代
java·人工智能
fortify36 分钟前
Git:从0掌握Git的使用,满足日常开发需求
后端
绵阳的脑内SSD37 分钟前
Lecture #20:Database Logging
后端
AirMan38 分钟前
深入浅出Redis:一文掌握Redis底层数据结构与实现原理
redis·后端·面试
Tim_1040 分钟前
【算法专题训练】02、二进制
java·开发语言·算法