浅谈序列化与反序列化

简介: 浅谈序列化与反序列化

什么是序列化?

序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)。 《维基百科》

粗略的说,我们可以将对象在内存中持有的属性称之为对象的状态,那么序列化的作用就就是保存对象的状态,类似于存档。像下面这样:

image.png

我们将学生对象写入到磁盘、内存、或者网络中,这个学生对象只拥有两个属性: age和name。然后JVM在将该对象从内存或磁盘或网络中加载进去,age还是20,name还是zs。

为什么要引入序列化?

java引入序列化主要是为了支持两种特性,一是 Java 的远程方法调用(Remote Method Invocation,RMI),它使存活于其他计算机上的对象使用起来就像是存活于本机上一样。当向远程对象发送消息时,需要通过对象序列化来传输参数和返回值。

再者,对 Java Beans 来说,对象的序列化也是必需的(在撰写本文时被视为失败的技术),使用一个 Bean 时,一般情况下是在设计阶段对它的状态信息进行配置。这种状态信息必须保存下来,并在程序启动时进行后期恢复,这种具体工作就是由对象序列化完成的。---《java编程思想》第四版

补充介绍内容:

谈谈我对java bean的序列化是一种失败的技术的理解:

这也许再说的是java默认的序列化机制,java默认的序列化机制有以下缺点:

  • 无法跨语言 只能被java语言自身所使用。
  • 码流太大    也就是说序列化出来的文件比较大,这会比较占用网络带宽。
  • 性能比较差  这也是有其他序列化机制出现的原因(后文会对常见的序列化机制做一个简单的介绍)

再有就是反序列化的时候是递归操作,解释一下,假设我们有这些类叫A、B、C、D。B是A的成员变量,C是B的成员变量,D是C的成员变量。我们反序列化A的时候,JVM会从最下面的一层去反序列化。众所周知,递归是和栈挂钩的,然后你引用关系比较深的话,栈就会承受不住,也就是stackOverflow。所以你反序列化的时候,引用关系就不要太深。

似乎在大数据领域会感受比较密切,参看这个回答:你什么时候对 Java 感到绝望?

为什么序列化需要实现Serializable接口?

用jdk提供的序列化,对应的类需要实现Serializable接口。如果你不用jdk提供的序列化,不实现Serializable接口也行。 Serializable接口属于标记接口,里面啥也没有,只是起一个标记作用,相当于一个标签。

刚开始我的想法是这个接口是用来判断哪些是需要序列化的,哪些是不需要序列化的,通过instanceof判断,如果实现了Serializable就是说明需要进行序列化的,没实现的就是不要进行序列化的。但是后来我又想,这不是应该由开发者来决定吗? 开发者觉得这个对象需要序列化了,就调用对应的方法将对象序列化,不需要的时候肯定不会调用啊。

稍微牵强一点的解释是,序列化接口和serialVersionUID(后文会介绍这个字段的作用)字段关联在一起,形成一种约定。image.png

你看在调用writeObject0方法时,就会校验序列化对象有没有实现Serializable接口,如果该类没有实现,就序列化不了。

默认序列化需要注意的点

每个实现了Serializable接口的类还有一个与之相关联的版本号,我们称之为serialVersionUID,他的作用是验证发送方发送的对象和接收方接收的对象是否是相容的,也就是看serialVersionUID是不是相等,如果不相等,那么反序列化就会失败。

一般来说,常用的IDE在类实现Serializable接口后,就会给一个警告,要求产生一个serialVersionUID,因为就算你不给,编译器根据java平台规范在运行时也会生成serialVersionUID,serialVersionUID的值和属性是有关系的,增加或减少一个属性都会引起serialVersionUID的变化。这也是官方建议要序列化的类(默认是使用jdk提供的序列化机制),务必给一个版本号,这是为了向前兼容,假设你不给,又增加了或减少了属性,序列化版本号就发生了变化,你反序列化之前的类,就会失败。 这也是阿里巴巴代码规约强调的:

序列化类新增属性时,勿修改 serialVersionUID 字段,否则会导致反序列化失败

常见的序列化框架简介

  • protostuff

google出品,跨语言,跨平台,性能强大。

  • FastJson

阿里出品,性能也比较强大,仅能在java平台使用,所支持的序列化也就是将json转成对象,对象转成json。 同类型的也有jackson,Gson,都能将JSON转成对象。

  • Hessian

粗略的说Hessian 是一个轻量级的RPC框架,也提供序列化功能。

总结一下

  • 什么是序列化?

将数据结构或对象状态转为可取用格式(txt、JSON) 。

  • 为什么需要序列化,或者说引入序列化机制?

宏观上来说,是为了暂存对象的状态,为了传递对象,比如说RMI。

  • 是不是序列化就一定需要实现Serializable接口?

不一定,需要看你调用对应序列化机制的协定。

相关文章
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
3月前
|
存储 开发框架 .NET
解锁SqlSugar新境界:利用Serialize.Linq实现Lambda表达式灵活序列化与反序列化,赋能动态数据查询新高度!
【8月更文挑战第3天】随着软件开发复杂度提升,数据查询的灵活性变得至关重要。SqlSugar作为一款轻量级、高性能的.NET ORM框架,简化了数据库操作。但在需要跨服务共享查询逻辑时,直接传递Lambda表达式不可行。这时,Serialize.Linq库大显身手,能将Linq表达式序列化为字符串,实现在不同服务间传输查询逻辑。结合使用SqlSugar和Serialize.Linq,不仅能够保持代码清晰,还能实现复杂的动态查询逻辑,极大地增强了应用程序的灵活性和可扩展性。
139 2
|
12天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
22天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
1月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第3天】在Java编程的世界里,对象序列化与反序列化是实现数据持久化和网络传输的关键技术。本文将深入探讨Java序列化的原理、应用场景以及如何通过代码示例实现对象的序列化与反序列化过程。从基础概念到实践操作,我们将一步步揭示这一技术的魅力所在。
|
22天前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
20 0
|
2月前
|
JSON fastjson Java
niubility!即使JavaBean没有默认无参构造器,fastjson也可以反序列化。- - - - 阿里Fastjson反序列化源码分析
本文详细分析了 Fastjson 反序列化对象的源码(版本 fastjson-1.2.60),揭示了即使 JavaBean 沲有默认无参构造器,Fastjson 仍能正常反序列化的技术内幕。文章通过案例展示了 Fastjson 在不同构造器情况下的行为,并深入探讨了 `ParserConfig#getDeserializer` 方法的核心逻辑。此外,还介绍了 ASM 字节码技术的应用及其在反序列化过程中的角色。
76 10
|
2月前
|
存储 XML JSON
用示例说明序列化和反序列化
用示例说明序列化和反序列化
|
2月前
|
存储 Java 开发者
Java编程中的对象序列化与反序列化
【9月更文挑战第20天】在本文中,我们将探索Java编程中的一个核心概念——对象序列化与反序列化。通过简单易懂的语言和直观的代码示例,你将学会如何将对象状态保存为字节流,以及如何从字节流恢复对象状态。这不仅有助于理解Java中的I/O机制,还能提升你的数据持久化能力。准备好让你的Java技能更上一层楼了吗?让我们开始吧!