`
逆天子军少
  • 浏览: 78774 次
  • 性别: Icon_minigender_1
  • 来自: 安庆
社区版块
存档分类
最新评论

(反)序列化

阅读更多

本章关注对象序列化API,它提供了一个框架,用来将对象编码成字节流,并从字节流中重新构建对象。“将对象编码成字节流”被称作对象序列化,相反的处理过程被称作反序列化。序列化技术为远程通信提供了标准的线路级对象表示法,也为JavaBeans组件结构提供了标准的持久化数据格式。

 

第七十四条:谨慎地实现Serializable接口

实现Serializable接口而付出的最大代价是,一旦一个类发布,就大大降低了“改变这个类实现”的灵活性。序列化会使类的演变受到限制,这与流的唯一标识符有关,通常它也被称为序列版本UID。每个可序列化的类都有一个唯一标识符与它相关联。如果你没有显示指定该标志号,系统就会自动根据这个类的名称,所实现接口的名称等计算出一个标志号。如果你改变了类,比如增加了一个工具方法,自动产生的UID会产生变化。因此,如果你没有显示声明UID,兼容性将遭到破坏。

第二个代价是,它增加了出现Bug和安全漏洞的可能性。序列化机制是一种语言之外的对象创建机制。反序列化是一个隐藏的构造器,具备和其他构造器相同的特点。所以要确保:反序列化过程必须要保证所有“由真正的构造器建立起来的约束关系”,并且不允许攻击者访问正在构造过程中的对象的内部信息。依靠默认的反序列化机制,很容易使对象的约束关系遭到破坏,以及遭到非法访问。

第三个代价,随着类发行新的版本,相关的测试负担也增加了。

根据经验,比如Date和BigInteger这样的值类应该实现Serializable,大多数的集合也应如此。代表活动实体的类比如线程池,一般不实现。

 

第七十五条:考虑使用自定义的序列化形式

如果一个对象的物理表示法等同于它的逻辑内容,可能就适合使用默认的序列化形式。即使你确认了默认的序列化形式是合适的,通常还必须提供一个readObject方法以保证约束关系和安全性。

当一个对象的物理表示法和逻辑数据内容有实质性的区别时,使用默认序列化形式会有下面四个缺点:

1.它使这个类的导出API永远的束缚在该类的内部表示法上。

2.消耗过多的空间。

3.消耗过多的时间。

4.引起栈溢出。

自定义序列化形式通常自定义writeObject和readObject方法,用来序列化和反序列化。同时,使用transient修饰符使实例域从一个类的默认序列化形式中省略掉。

 

第七十六条:保护性的编写readObject方法

不严格地说,readObject是一个“用字节流作为唯一参数”的构造器。在正常使用的情况下,对一个正常构造的实例进行序列化可以产生字节流。但是,当面对一个人工仿造的字节流时,readObject产生的对象可能会违反所属的类的约束条件。

为了解决这个问题,可以为实现默认序列化的类添加一个readObject方法,该方法首先调用defaultReadObject,然后检查被反序列化之后对象的有效性。但这样仍可能解决不了问题,攻击者可以使用对象引用来修改实例的内部组件。当一个对象被反序列化的时候,对于客户端不应该拥有的对象应用,如果哪个域包含了这样的对象引用,就必须要做保护性拷贝。并且,保护性拷贝是在有效性检查之前进行。

下面的建议有利于编写更加健壮的readObject方法:

1.对于对象引用域必须保持为私有的类,要保护性地拷贝这些域中的每个对象。不可变类的可变组件就属于这一类别。

2.对于任何约束条件,如果检查失败,抛出InvalidObjectException异常。这些检查跟在所有保护性拷贝之后。

3.如果整个对象在被反序列化之后必须进行验证,就应该使用ObjectInputValidation接口

4.不要调用类中可能被覆盖的方法。

 

第七十七条:对于实例控制,枚举类型优先于readResolve

readResolve特性允许你用readObject创建的实例代替另一个实例。对于一个正在被反序列化的对象,如果他的类定义了一个readResolve方法,并且具备正确的声明,那么在反序列化之后,新建对象上的readResolve方法就会被调用。然后该方法返回的对象引用被返回,取代新建的对象。

尽可能使用枚举类型来实施实例控制的约束条件。如果做不到,同时又需要一个既可序列化又是实例受控的类,就必须提供一个readResolve方法,并确保该类的所有实例域都为基本类型或者是transient的。

 

第七十八条:考虑用序列化代理代替序列化实例

序列化代理模式相当简单。首先,为可序列化的类设计一个私有的静态嵌套类,精确地表示外围类的实例的逻辑状态。这个嵌套类被称作序列化代理,它应该有一个单独的构造器,其参数类型就是那个外围类。这个构造器只从它的参数中复制数据:他不需要进行任何一致性检查或者保护性拷贝。从设计的角度看,序列化代理的默认序列化形式是外围类最好的序列化形式。外围类及其序列代理都必须声明Serializable接口。

 

分享到:
评论

相关推荐

    C++ JSON 序列化与反序列化

    本篇文章将深入探讨C++中JSON的序列化与反序列化。 **一、JSON序列化** 序列化是指将C++的对象转换为JSON字符串的过程,以便在网络上传输或保存到文件中。常见的C++ JSON序列化库有RapidJSON、nlohmann/json、...

    ASPNET中JSON的序列化和反序列化的方法

    在***中处理JSON的序列化和反序列化是Web开发中常见的需求。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,由于其简洁性和易于阅读性,被广泛用于服务器与客户端之间的数据传输。下面将详细介绍**...

    java反序列化工具

    Java反序列化是一种将已序列化的对象状态转换回对象的过程,它是Java平台中持久化数据的一种常见方式。在Java应用程序中,序列化用于保存对象的状态以便稍后恢复,或者在网络间传输对象。然而,这个过程也可能引入...

    java 对象的序列化与反序列化

    Java对象的序列化和反序列化是Java编程中一项重要的技术,主要用于将对象的状态转换为字节流,以便存储或在网络上传输。这一过程对于理解Java的IO操作、持久化数据以及实现分布式通信等场景非常关键。 首先,我们来...

    Json反序列化

    反序列化是将JSON格式的字符串转换为程序可直接使用的对象的过程,这对于处理网络请求返回的数据至关重要。在本篇文章中,我们将深入探讨JSON反序列化的概念、原因以及在实际开发中的应用。 一、什么是JSON反序列化...

    C#和Java的序列化反序列化

    在编程领域,序列化和反序列化是两个关键的概念,特别是在跨平台通信、持久化存储以及数据传输中扮演着重要角色。本篇文章将深入探讨C#和Java中的序列化与反序列化机制。 首先,我们要了解什么是序列化。序列化是指...

    序列化和反序列化dll文件和proto

    在IT领域,序列化和反序列化是两个关键的概念,特别是在数据存储、网络通信和分布式系统中。它们涉及将对象的状态转换为可持久化的格式(序列化),以及将这种格式还原回原来的对象(反序列化)。本文将深入探讨这两...

    基于boost的序列化与反序列化

    在编程领域,序列化和反序列化是两个关键的概念,它们用于将对象的状态转换为可存储或可传输的格式,然后在需要时恢复为原始对象。Boost库提供了一个强大的工具——Boost.Serialization,来帮助程序员实现这个功能。...

    序列化和反序列化的封装类

    在编程领域,序列化和反序列化是两个关键的概念,特别是在数据存储、网络传输和对象持久化等场景中。它们允许我们将对象的状态转换为字节流(序列化),然后在需要的时候将字节流还原为原来的对象(反序列化)。在C#...

    XML序列化与反序列化 实战

    XML序列化与反序列化是.NET框架中处理数据交换的重要技术,它允许我们将对象的状态转换为XML格式的数据,也可以将XML数据恢复为等效的对象。这个实战项目专注于使用C#实现这一过程,使得开发者能够方便地在XML文件和...

    C#序列化与反序列化(包括复杂xml对象)

    在C#编程中,序列化和反序列化是两个关键的概念,它们主要用于对象状态的持久化和恢复。本文将深入探讨C#中的XML序列化和反序列化技术,包括如何将XML文档解析为对象,以及如何将对象转换回XML文档进行存储。我们将...

    hessian学习基础篇——序列化和反序列化

    在IT领域,序列化和反序列化是两个关键的概念,特别是在网络通信、数据持久化以及对象存储中。本文将深入探讨Hessian框架的基础知识,它是一个高效的二进制序列化协议,广泛应用于Java和.NET之间跨语言通信。通过...

    jackson json序列化,反序列化所需jar包

    Jackson是Java领域中广泛使用的JSON处理库,它提供了高效的JSON序列化和反序列化功能。在Java应用程序中,我们经常需要将Java对象转换为JSON字符串(序列化)或从JSON字符串恢复Java对象(反序列化),Jackson库就是...

    json数据序列化和反序列化

    在IT领域,JSON数据序列化和反序列化是数据处理的重要环节,尤其在Web开发中,它们在客户端与服务器之间传递数据时起到关键作用。 1. JSON数据格式:JSON数据由键值对组成,键用引号包围,然后冒号分隔,接着是值。...

    protobuf序列化和反序列化技术

    protobuf序列化和反序列化技术是大数据处理领域中不可或缺的一部分,尤其在实时大数据场景下,高效的数据传输和存储对性能有着直接影响。谷歌推出的Protocol Buffers(简称protobuf)是一种语言无关、平台无关的数据...

    Xml反序列化

    Xml反序列化是编程中一个重要的概念,尤其是在.NET框架中,它允许我们将XML文档的数据转换为等效的程序对象,反之亦然。这个过程对于数据交换、存储和恢复有着广泛的应用,尤其在需要将XML文件作为持久化数据格式时...

    java序列化和反序列化的方法

    java 序列化和反序列化的方法 Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在...

    C# 后台序列化Json序列、反序列化Json序列(三种方法)

    在.NET开发中,C#语言提供了多种方式来处理JSON序列化和反序列化,这对于数据交换和存储至关重要。本文将详细介绍C#中处理JSON的三种主要方法:使用Json.NET库(Newtonsoft.Json)、使用.NET Framework自带的System....

    学生管理系统(序列化和反序列化)

    在本项目中,“学生管理系统(序列化和反序列化)”是一个基于Java或类似编程语言实现的系统,其核心功能是有效地存储和恢复学生信息。序列化和反序列化是这个系统的关键技术,它们允许程序将对象的状态转化为可存储...

    java序列化(Serializable)的作用和反序列化.doc

    ### Java序列化(Serializable)的作用与反序列化详解 #### 一、序列化的概念 序列化是指将程序中的对象转换为一系列字节流的过程,主要用于保存对象的状态或在网络之间传输对象。序列化的主要目的是为了能够持久化...

Global site tag (gtag.js) - Google Analytics