【JavaSE专栏21】序列化和反序列化,学会Java的编解码方法

简介: 【JavaSE专栏21】序列化和反序列化,学会Java的编解码方法

序列化:将 Java 对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存 Java 对象状态的过程,序列化可以将数据永久保存在磁盘上。

反序列化:将保存在磁盘文件中的 Java 字节码重新转换成 Java 对象称为反序列化。

省流:最核心的概念已在上面展示,如您还是不懂请往下看!

一、什么是序列化

序列化是指将对象转换为字节流的过程,以便可以在网络上传输或保存到文件中,反序列化则是将字节流转换回对象的过程。

在 Java 中,要使一个类可序列化,需要实现 java.io.Serializable 接口,以下是一个示例代码。

import java.io.*;
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 int getAge() {
        return age;
    }
}
public class SerializationExample {
    public static void main(String[] args) {
        // 创建一个Person对象
        Person person = new Person("Alice", 25);
        // 将对象进行序列化
        try {
            FileOutputStream fileOut = new FileOutputStream("person.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(person);
            out.close();
            fileOut.close();
            System.out.println("对象已成功序列化到文件中!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 将序列化后的对象进行反序列化
        try {
            FileInputStream fileIn = new FileInputStream("person.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Person deserializedPerson = (Person) in.readObject();
            in.close();
            fileIn.close();
            System.out.println("从文件中反序列化得到的对象:");
            System.out.println("姓名:" + deserializedPerson.getName());
            System.out.println("年龄:" + deserializedPerson.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,Person 类实现了 Serializable 接口。首先,我们创建一个 Person 对象,并将其序列化到名为 person.ser 的文件中。然后,我们从文件中读取序列化的对象并进行反序列化,最终恢复了原始的 Person 对象。

请注意,在序列化和反序列化过程中,我们使用 ObjectOutputStreamObjectInputStream 来分别写入和读取字节流。通过 writeObject() 方法将对象写入输出流,然后通过 readObject() 方法从输入流中读取对象。

运行上述代码,同学们将会得到以下输出。

对象已成功序列化到文件中!
从文件中反序列化得到的对象:
姓名:Alice
年龄:25

这个例子演示了 Java 中序列化和反序列化的基本概念和用法,通过序列化,我们可以方便地保存和传输对象数据,而不需要手动处理字节流


二、什么是反序列化

反序列化是将对象从持久化状态恢复为内存中的对象的过程,在Java中,我们可以使用 ObjectInputStream 类来进行反序列化操作,下面是一个简单的示例代码。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializationExample {
    public static void main(String[] args) {
        try {
            // 创建FileInputStream对象读取序列化后的对象
            FileInputStream fileIn = new FileInputStream("serialized_object.ser");
            // 创建ObjectInputStream对象读取对象
            ObjectInputStream in = new ObjectInputStream(fileIn);
            // 反序列化对象
            Person person = (Person) in.readObject();
            // 输出反序列化后的对象信息
            System.out.println("姓名:" + person.getName());
            System.out.println("年龄:" + person.getAge());
            // 关闭输入流
            in.close();
            fileIn.close();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在上述示例中,我们从名为 serialized_object.ser 的文件中读取序列化后的对象,并通过 ObjectInputStream 进行反序列化。然后,我们将恢复的 Person 对象的属性打印到控制台上。

请注意,在进行反序列化之前,必须确保序列化和反序列化过程中使用的类具有相同的 serialVersionUID。否则,在反序列化时可能会引发 InvalidClassException


三、为什么要进行序列化和反序列化

3.1 主要目的

Java 进行序列化和反序列化的主要目的是在不同的场景中实现对象的持久化和数据传输

  • 持久化:通过序列化,可以将对象保存到磁盘或数据库中,以便在程序重启后恢复对象的状态。这对于需要长时间存储对象或进行数据持久化的应用程序非常有用。
  • 数据传输:通过序列化,可以将对象转换为字节流,在网络上传输或进行远程方法调用。序列化使得在分布式系统中传递对象变得更简单,可以轻松地在客户端和服务器之间传递对象,并确保对象的完整性和一致性。
  • 缓存和缓存共享:通过序列化,可以将对象存储在缓存中,以提高性能。对象可以被序列化后存储在内存或磁盘上,当需要时可以快速从缓存中加载而无需重新创建对象。
  • 对象传递:通过序列化,可以方便地在进程之间传递对象。在多线程编程或分布式系统中,通过将对象序列化并传递给其他线程或进程,可以实现数据共享和通信。

总的来说,序列化和反序列化提供了一种机制,可以将对象转换为字节流,以便持久化、传输和共享数据。它在许多应用程序中被广泛使用,包括数据库操作、网络通信和分布式系统等。

3.2 应用场景

序列化和反序列化在许多应用场景中起到关键作用,以下是一些常见的应用场景:

缓存:将对象序列化后,可以将其存储在缓存中,以提高性能和响应速度。当需要时,可以从缓存中快速加载对象,而无需重新创建或计算。

分布式系统:在分布式系统中,对象需要在不同的节点之间传递。通过将对象序列化为字节流,可以在网络上进行传输,并在远程服务之间共享数据。

持久化:通过序列化,可以将对象保存到文件、数据库或其他持久化存储中。这样,在应用程序重启后,可以从存储中读取序列化的对象并还原其状态。

远程方法调用:通过序列化和反序列化,可以在不同的计算机上执行远程过程调用。客户端将请求参数序列化为字节流,发送给远程服务器,服务器接收到字节流后进行反序列化,执行相应的方法,并将结果序列化并返回给客户端。

数据传输和消息传递:在网络通信中,通过将对象序列化为字节流,可以轻松地传输和接收复杂的数据结构、消息和事件。

克隆对象:通过序列化和反序列化,可以实现对象的深度克隆。序列化对象后,创建一个完全独立的副本。

需要注意的是,在某些场景下,使用序列化和反序列化可能会带来性能上的开销,因此,在设计应用程序时,需要权衡考虑序列化和反序列化的成本与收益,并根据具体需求选择合适的方案。


四、总结

序列化是将Java对象以一连串的字节保存在磁盘文件中的过程,序列化可以将数据永久保存在磁盘上;反序列化是将保存在磁盘文件中的Java字节码重新转换成Java对象的过程。

本文对 Java 的序列化和反序列化进行了介绍,讲解了如何在实际业务中使用序列化和反序列化,并给出了 Java 样例代码。在下一篇博客中,将讲解 Java 中的正则表达式规则和使用方式。

相关文章
|
1月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
1月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
74 9
|
29天前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
41 4
|
29天前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
30 4
|
27天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
26 1
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
133 4
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
JSON JavaScript 前端开发
|
1月前
|
存储 安全 Java
🌟Java零基础-反序列化:从入门到精通
【10月更文挑战第21天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
84 5
|
1月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
213 2