【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 中的正则表达式规则和使用方式。

相关文章
|
14天前
|
Java
Java——方法的引用
方法引用允许将已有方法作为函数式接口的实现。使用“::”符号,需具备函数式接口,被引用的方法须存在且参数和返回值需与抽象方法一致。其分类包括:静态方法引用(类::方法名)、成员方法引用(对象::方法名、this::方法名、super::方法名)和构造方法引用(类名::new)。方法引用提高了代码的简洁性和可读性,减少了样板代码。
29 13
Java——方法的引用
|
10天前
|
Java
java基础(12)抽象类以及抽象方法abstract以及ArrayList对象使用
本文介绍了Java中抽象类和抽象方法的使用,以及ArrayList的基本操作,包括添加、获取、删除元素和判断列表是否为空。
13 2
java基础(12)抽象类以及抽象方法abstract以及ArrayList对象使用
|
6天前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
18 4
|
8天前
|
安全 Java API
Java根据URL获取文件内容的实现方法
此示例展示了如何安全、有效地根据URL获取文件内容。它不仅展现了处理网络资源的基本技巧,还体现了良好的异常处理实践。在实际开发中,根据项目需求,你可能还需要添加额外的功能,如设置连接超时、处理HTTP响应码等。
44 4
|
6天前
|
存储 XML JSON
用示例说明序列化和反序列化
用示例说明序列化和反序列化
|
14天前
|
JSON fastjson Java
niubility!即使JavaBean没有默认无参构造器,fastjson也可以反序列化。- - - - 阿里Fastjson反序列化源码分析
本文详细分析了 Fastjson 反序列化对象的源码(版本 fastjson-1.2.60),揭示了即使 JavaBean 沲有默认无参构造器,Fastjson 仍能正常反序列化的技术内幕。文章通过案例展示了 Fastjson 在不同构造器情况下的行为,并深入探讨了 `ParserConfig#getDeserializer` 方法的核心逻辑。此外,还介绍了 ASM 字节码技术的应用及其在反序列化过程中的角色。
42 10
|
15天前
|
Java API
Java方法的优缺点
Java 方法是编程的基本构建块,具有代码重用性、模块化、易于调试、增强可读性、支持重载和可变参数、封装性及静态与实例方法的灵活性等优点,但也存在性能开销、过度抽象、限制使用环境、参数传递开销、命名冲突和堆栈溢出等缺点。合理设计方法可确保代码高效且易维护。
|
10天前
|
安全 Java
java调用方法
java调用方法
18 4
|
8天前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
14天前
|
存储 Java 开发者
Java编程中的对象序列化与反序列化
【9月更文挑战第20天】在本文中,我们将探索Java编程中的一个核心概念——对象序列化与反序列化。通过简单易懂的语言和直观的代码示例,你将学会如何将对象状态保存为字节流,以及如何从字节流恢复对象状态。这不仅有助于理解Java中的I/O机制,还能提升你的数据持久化能力。准备好让你的Java技能更上一层楼了吗?让我们开始吧!
下一篇
无影云桌面