展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Java中对象的转移之序列化与反序列化方式

Java中对象的转移之序列化与反序列化方式

序列化将对象转换为字节流以便存储或传输,反序列化则将其还原。Java通过Serializable接口和ObjectOutputStream/ObjectInputStream实现该过程,transient关键字可保护敏感字段。原生序列化存在性能、跨语言及安全问题,因此常采用FastJson或Protobuf等替代方案,它们分别提供跨平台JSON处理与高效二进

本文目录

    1. 序列化与反序列化的定义与实现流程

    在分布式系统、缓存以及跨应用数据交换的场景中,我们经常需要将对象“打包”发送或“封存”起来。这背后依赖的核心技术,就是序列化与反序列化。

    Ja va中对象的转移之序列化与反序列化方式

    序列化是什么?

    简单来说,序列化就是把一个活生生的对象,转换成一串连续的字节流。这个过程就好比把一件复杂的家具拆解、打包成一个规整的包裹,目的是为了方便存储到文件或数据库,或者通过网络“寄送”到另一个系统。

    反序列化是什么?

    反序列化自然是序列化的逆过程。当系统收到这个“包裹”或者从存储介质中读取到这串字节流时,需要按照原来的图纸,把零件重新组装成完整的家具对象。这个过程就是反序列化,它让字节流重新获得生命,变回可操作的程序对象。

    序列化的实现流程

    整个流程可以清晰地分为三步走:

    第一步:对象状态转换为字节流

    • 系统会提取对象的所有属性、数据结构以及类标识等信息,将它们编码成一组有序的字节。
    • 这组字节不仅包含了字段的值,还隐含了对象的“出生证明”(类信息),确保接收方能准确识别并还原。

    第二步:传输或存储字节流

    • 生成的字节流可以被写入文件系统、存入数据库,或者直接通过网络套接字发送到远程服务器。

    第三步:将字节流转为对象(反序列化)

    • 当需要用到这个对象时,系统会读取字节流,根据其中包含的类信息和字段数据,在内存中重新构造出一个状态完全相同的对象实例。

    正是这套机制,实现了对象跨越时间(持久化)和空间(网络传输)的转移。虽然这里以Ja va为例,但序列化的思想在众多编程语言和框架中都有体现,只是实现方式各有千秋。

    2. Ja va中的序列化与反序列化实现

    Ja va语言内置了一套完整的序列化机制,让对象转换变得非常直接。其核心是Serializable接口和一对流类:ObjectOutputStream与ObjectInputStream。

    1.Serializable接口:标识对象可序列化

    想让一个类的对象能被序列化,第一步就是让它实现Serializable接口。这个接口没有任何方法,是一个纯粹的“标记接口”,它的作用就是告诉JVM:“我这个类的对象可以被序列化。”

    示例:

    import ja va.io.Serializable;
    
    public class Person implements Serializable {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        // 省略getters和setters
    }
    

    解释: 上面的Person类实现了Serializable接口。这意味着,这个类的所有实例字段(除非被特殊标记)在序列化时都会被自动转换成字节流。

    2.ObjectOutputStream和ObjectInputStream:读写字节流的对象

    • ObjectOutputStream:负责将对象“写出去”,即执行序列化操作。
    • ObjectInputStream:负责将字节流“读进来”,即执行反序列化操作。

    示例:序列化对象

    import ja va.io.FileOutputStream;
    import ja va.io.ObjectOutputStream;
    
    public class SerializeExample {
        public static void main(String[] args) {
            Person person = new Person("Alice", 30);
    
            try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
                oos.writeObject(person); // 将Person对象写入文件
                System.out.println("对象已序列化");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    解释:

    1. 代码创建了一个ObjectOutputStream,并将其链接到一个文件输出流。
    2. 调用writeObject方法,person对象的状态便被序列化并写入person.ser文件中。
    3. 至此,对象的数据已被持久化保存。

    示例:反序列化对象

    import ja va.io.FileInputStream;
    import ja va.io.ObjectInputStream;
    
    public class DeserializeExample {
        public static void main(String[] args) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
                Person person = (Person) ois.readObject(); // 从文件中读取对象
                System.out.println("对象已反序列化: " + person.getName() + ", " + person.getAge());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    解释:

    1. 代码创建ObjectInputStream来读取之前保存的文件。
    2. 调用readObject方法,字节流被重新解析,还原成一个Person对象。
    3. 最后,打印出对象的信息,验证反序列化成功。

    3.transient关键字:保护敏感数据

    序列化会包含所有非静态字段。但如果有些字段(比如密码、密钥)不希望被持久化或传输,该怎么办?这时就需要transient关键字出场了。用它修饰的字段,会在序列化过程中被自动忽略。

    示例:

    public class User implements Serializable {
        private String username;
        private transient String password; // 不会被序列化
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    }
    

    在这个例子中,即使用户对象被序列化,password字段也不会被写入字节流,从而在存储或传输时保护了敏感信息。

    4.Externalizable接口:自定义序列化逻辑

    对于更复杂的控制需求,Ja va提供了Externalizable接口。它继承自Serializable,但要求开发者自己动手,完全掌控序列化和反序列化的每一个细节。实现它需要重写两个方法:

    • writeExternal(ObjectOutput out):定义如何将对象写入字节流。
    • readExternal(ObjectInput in):定义如何从字节流中读取并重建对象。

    示例:

    import ja va.io.Externalizable;
    import ja va.io.ObjectOutput;
    import ja va.io.ObjectInput;
    
    public class Book implements Externalizable {
        private String title;
        private double price;
    
        public Book() {} // 必须有无参构造方法
    
        public Book(String title, double price) {
            this.title = title;
            this.price = price;
        }
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeUTF(title);
            out.writeDouble(price);
        }
    
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            title = in.readUTF();
            price = in.readDouble();
        }
    }
    

    解释:

    • 在writeExternal方法中,我们明确指定了将title和price字段以何种顺序、何种格式写入流中。
    • 在readExternal方法中,我们按照写入的顺序和格式,再将数据读取出来,赋值给对象的字段。
    • 这种方式牺牲了便利性,换来了极高的灵活性和控制力,适用于有特殊序列化需求的场景。

    总的来说,Ja va内置的序列化机制为开发者提供了从便捷到灵活的不同选择。Serializable搭配ObjectOutputStream/ObjectInputStream足以应对大多数常规需求。而当需要对过程进行精细控制时,Externalizable接口则提供了强大的自定义能力。

    3. Ja va序列化的缺点和替代方案

    尽管Ja va原生序列化用起来方便,但在构建高性能、跨平台、高安全的现代分布式系统时,它的几个固有缺陷就会变得非常突出。

    Ja va序列化的缺点

    性能较差:

    • Ja va序列化生成的字节流包含了大量元数据(如完整的类描述信息),导致数据体积臃肿。序列化和反序列化的过程也涉及大量反射操作,速度相对较慢。在处理海量数据或高并发请求时,这很容易成为性能瓶颈。

    不跨语言:

    • 它生成的是一种Ja va特有的二进制格式。这意味着,用Ja va序列化保存的数据,几乎无法被C++、Python、Go等其他主流语言直接解析。在微服务架构和多语言技术栈并存的今天,这无疑是一个巨大的限制。

    存在安全漏洞:

    • Ja va反序列化机制历史上存在严重的安全隐患。攻击者可以精心构造一个恶意的序列化字节流,当程序对其进行反序列化时,可能触发任意代码执行。这使得它不适合处理来自不可信源的数据。

    缺乏版本控制:

    • 当序列化后的类结构发生变化(例如增删字段),反序列化很容易失败。虽然可以通过手动维护serialVersionUID来缓解,但在复杂的项目迭代中,维护版本兼容性依然是个头疼的问题。

    正因为这些局限性,在实际生产环境中,尤其是对性能、安全性和跨语言能力有要求的场景下,开发者往往会转向更优秀的替代方案。下面就来聊聊两个主流选择:FastJson和Protobuf。

    替代方案一:FastJson

    FastJson是阿里巴巴开源的高性能JSON处理库。它的核心是将Ja va对象与JSON格式相互转换,而JSON是一种几乎无处不在的、人类可读的数据交换格式。

    FastJson的优势:

    跨平台:

    • JSON是标准的数据格式,所有编程语言都支持解析和生成。因此,用FastJson序列化的数据可以毫无障碍地在Ja va、前端Ja vaScript、Python后端等不同组件间传递。

    速度快,性能优异:

    • 正如其名,FastJson在速度上做了大量优化,其序列化/反序列化性能通常远超Ja va原生序列化,甚至优于许多其他JSON库。

    支持灵活的数据结构:

    • 基于JSON的键值对特性,FastJson能很好地处理动态或结构易变的数据。即使类的字段有增减,反序列化时也能通过字段名进行匹配,兼容性更好。

    安全性更高:

    • JSON格式本身不携带可执行代码,从根本上避免了Ja va原生反序列化漏洞。同时,FastJson也提供了安全模式,可以限制反序列化的类,进一步加固安全。

    FastJson使用示例:

    import com.alibaba.fastjson.JSON;
    
    public class FastJsonExample {
        public static void main(String[] args) {
            // 序列化
            Person person = new Person("Alice", 25);
            String jsonString = JSON.toJSONString(person);
            System.out.println("序列化为JSON字符串:" + jsonString);
    
            // 反序列化
            Person deserializedPerson = JSON.parseObject(jsonString, Person.class);
            System.out.println("反序列化对象:" + deserializedPerson.getName());
        }
    }
    

    替代方案二:Protobuf

    Protobuf(Protocol Buffers)是Google推出的一种语言中立、平台无关、可扩展的序列化机制。它追求的是极致的效率和紧凑性。

    Protobuf的优势:

    高效的二进制格式:

    • Protobuf将数据编码成非常紧凑的二进制格式,体积远小于JSON或Ja va原生序列化结果。其编码和解码速度也极快,专为高性能网络通信设计。

    跨语言:

    • 通过预先定义.proto文件,Protobuf编译器可以生成Ja va、C++、Python、Go等多种语言的代码。不同语言编写的服务可以使用同一份数据定义进行无缝通信。

    支持严格的版本控制:

    • Protobuf的协议设计天生支持向前和向后兼容。新增或废弃字段不会破坏旧版程序的解析,大大简化了系统升级和数据迁移的复杂度。

    安全性强:

    • 由于其强类型和预定义结构的特性,Protobuf不易受到不可控反序列化攻击,安全性比Ja va原生序列化高得多。

    Protobuf使用示例: 使用Protobuf首先需要定义一个.proto文件来描述数据结构:

    // person.proto
    syntax = "proto3";
    
    message Person {
        string name = 1;
        int32 age = 2;
    }
    

    然后,使用Protobuf编译器生成对应的Ja va类,之后就可以像下面这样使用:

    Person person = Person.newBuilder().setName("Alice").setAge(25).build();
    byte[] data = person.toByteArray(); // 序列化
    Person deserializedPerson = Person.parseFrom(data); // 反序列化
    

    简单来说,FastJson以其通用性和可读性见长,非常适合前后端交互和需要日志调试的场景。而Protobuf则以绝对的性能和跨语言能力取胜,是微服务、分布式存储等对效率和带宽敏感场景的首选。两者都有效地弥补了Ja va原生序列化的短板。

    4. 总结

    序列化与反序列化是构建可交互、可扩展软件系统的基石技术。它们让对象得以跨越进程、网络甚至语言的边界,是实现数据持久化和远程通信的关键。

    1. Ja va原生序列化的基础

    Ja va通过Serializable接口和ObjectOutputStream/ObjectInputStream这一套组合拳,提供了开箱即用的序列化支持。其流程直观:对象变字节流,存储或传输;字节流再变回对象,恢复状态。这套方案在单一的Ja va环境中简单快捷。

    2. Ja va原生序列化的缺点

    然而,一旦进入生产环境,面对性能、安全、跨语言的需求,原生序列化的局限性便暴露无遗:

    • 性能低:生成的负载大,处理速度慢。
    • 不跨语言:二进制格式与其他语言不兼容。
    • 安全性欠佳:存在已知的反序列化安全漏洞。

    因此,它更适用于简单的、临时的、信任边界内的数据存储场景。

    3. 替代方案:FastJson和Protobuf

    为了应对更复杂的挑战,业界广泛采用了更先进的序列化方案:

    • FastJson:在需要人类可读、跨平台(尤其是Web前后端)且对性能有一定要求的场景下表现出色。JSON格式的通用性是其最大优势。
    • Protobuf:在追求极致性能、低带宽消耗和严格跨语言兼容的分布式系统、微服务架构中几乎是标准选择。其二进制格式高效且安全。

    使用场景总结

    • 选择Ja va原生序列化:适用于简单的Ja va进程内缓存、Session存储等封闭场景。
    • 选择FastJson:适用于前后端API交互、配置文件存储、需要人工查看和调试数据的场景。
    • 选择Protobuf:适用于服务间RPC通信、大数据量持久化、多语言微服务集群等对效率和兼容性要求极高的场景。

    技术选型没有银弹,关键在于理解不同序列化工具的特性,并根据实际应用场景在性能、可读性、安全性和开发成本之间做出平衡。选择合适的序列化方案,能显著提升系统的整体健壮性和效率。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Postman macOS版
    Postman macOS版

    Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。

    Docker Desktop macOS版
    Docker Desktop macOS版

    Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。

    Android Studio macOS版
    Android Studio macOS版

    Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

    Xcode macOS版
    Xcode macOS版

    Xcode 是苹果面向 Mac 提供的官方集成开发环境,将代码编辑、项目构建、SwiftUI 实时预览、设备模拟、自动化测试、断点调试、性能分析和应用分发整合在同一套工作流中,适合开发与维护 iPhone、iPad、Mac、Apple Wa

    JetBrains WebStorm macOS版
    JetBrains WebStorm macOS版

    JetBrains WebStorm 是面向 JavaScript、TypeScript 和现代 Web 技术的专业集成开发环境,可智能理解项目结构,提供代码补全、重构、错误检查、运行调试、测试及 Git 工具。

    PhpStorm macOS版
    PhpStorm macOS版

    PhpStorm 是 JetBrains 推出的专业 PHP 集成开发环境,可在 Mac 上完成代码编写、智能检查、重构、调试、测试和数据库管理。它支持主流 PHP 框架、Composer、Git、Docker 与远程解释器。

    JetBrains PyCharm macOS版
    JetBrains PyCharm macOS版

    JetBrains PyCharm 是面向 Python 开发者的集成开发环境,提供智能补全、代码检查、重构、调试、测试、版本控制及虚拟环境管理功能。Mac 版兼容 Intel 与 Apple 芯片,核心功能可免费使用。

    JetBrains IntelliJ IDEA macOS版
    JetBrains IntelliJ IDEA macOS版

    IntelliJ IDEA 是 JetBrains 推出的专业集成开发环境,重点服务于 Java、Kotlin 与 JVM 项目开发。软件集成代码补全、静态检查、重构、调试、测试、版本控制及构建工具,并可借助插件扩展语言和框架支持。

    Visual Studio Code macOS版
    Visual Studio Code macOS版

    Visual Studio Code 是微软提供的免费代码编辑器,支持 macOS,并为 Intel 与 Apple 芯片 Mac 提供适配版本。软件集代码编辑、调试、Git 源代码管理、集成终端和扩展市场于一体。

    REAPER macOS版
    REAPER macOS版

    REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

    Adobe Audition macOS版
    Adobe Audition macOS版

    Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

    Pro Tools macOS版
    Pro Tools macOS版

    Pro Tools 是 Avid 推出的专业数字音频工作站,覆盖多轨录音、无损剪辑、MIDI 编曲、插件处理、自动化混音及声音与画面同步等工作。它拥有 Intro、Artist、Studio 和 Ultimate 等方案。

    WINDOWS 更多
    Postman Windows版
    Postman Windows版

    Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等

    Docker Desktop Windows版
    Docker Desktop Windows版

    Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。

    Android Studio Windows版
    Android Studio Windows版

    Android Studio 是 Google 面向 Android 应用开发提供的官方集成开发环境,以 IntelliJ IDEA 为基础,集成智能代码编辑、Gradle 构建、设备模拟、界面预览、调试测试及性能分析工具,

    JetBrains WebStorm Windows版
    JetBrains WebStorm Windows版

    WebStorm 是 JetBrains 面向 JavaScript、TypeScript 和现代 Web 技术打造的集成开发环境。它提供项目级代码分析、智能补全、安全重构、导航搜索,并集成调试、测试、终端、Git 与常用前端工具,

    JetBrains PhpStorm Windows版
    JetBrains PhpStorm Windows版

    PhpStorm 是 JetBrains 面向 PHP 与现代 Web 开发打造的专业集成开发环境,提供代码补全、静态检查、重构、调试、测试、数据库、版本控制及前端语言支持。Windows 用户可直接下载安装程序,

    JetBrains PyCharm Windows版
    JetBrains PyCharm Windows版

    PyCharm 是 JetBrains 推出的 Python 集成开发环境,提供智能代码补全、错误检查、重构、调试、测试、Git、终端及 Jupyter Notebook 支持。统一版安装后可体验 30 天 Pro 功能,

    JetBrains IntelliJ IDEA Windows版
    JetBrains IntelliJ IDEA Windows版

    JetBrains IntelliJ IDEA 是以 Java、Kotlin 和 JVM 项目为核心的专业集成开发环境,提供智能补全、代码检查、安全重构、调试、测试、版本控制及构建工具集成。统一发行版的核心功能可免费用于商业和非商业项目,

    Visual Studio Code Windows版
    Visual Studio Code Windows版

    Visual Studio Code 是微软推出的免费代码编辑器,Windows 版集成智能补全、代码导航、调试、终端和版本控制,并可通过扩展添加语言、格式化及远程开发能力。它启动较快、配置灵活,

    REAPER Windows版
    REAPER Windows版

    REAPER 是 Cockos 推出的数字音频工作站,适用于录音、MIDI 编曲、音频编辑、混音、母带制作及声音设计。软件安装包小巧,支持多轨录制、灵活路由、自动化、第三方插件和脚本扩展,并提供完整功能的 60 天免费评估期。

    Adobe Audition Windows版
    Adobe Audition Windows版

    Adobe Audition 是面向播客、影视后期、广播与音乐制作的专业音频工作站,提供波形编辑、多轨混音、频谱分析、录音、降噪修复和效果处理等功能。Windows 版通过 Adobe Creative Cloud 安装和管理,

    Pro Tools Windows版
    Pro Tools Windows版

    Pro Tools 是 Avid 推出的专业数字音频工作站,提供多轨录音、音频剪辑、MIDI编曲、插件处理、自动化混音及影视声音制作能力。它适合音乐人、录音师、制作人和音频后期团队使用,并提供免费入门版、订阅方案及永久授权选择。

    Cubase Windows版
    Cubase Windows版

    Cubase 是 Steinberg 推出的数字音频工作站,提供 MIDI 编曲、多轨录音、音频编辑、虚拟乐器、效果处理、自动化、混音和母带输出工具。其 Pro、Artist 与 Elements 版本面向不同预算和制作规模,