《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.4.5 版本管理

简介: 本节书摘来华章计算机《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一书中的第2章 ,第2.4.5节,[美] 凯S.霍斯特曼(Cay S. Horstmann) 著陈昊鹏 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.4.5 版本管理

如果使用序列化来保存对象,就需要考虑在程序演化时会有什么问题。例如,1.1版本可以读入旧文件吗?仍旧使用1.0版本的用户可以读入新版本产生的文件吗?显然,如果对象文件可以处理类的演化问题,那它正是我们想要的。
乍一看,这好像是不可能的。无论类的定义产生了什么样的变化,它的SHA指纹也会跟着变化,而我们都知道对象输入流将拒绝读入具有不同指纹的对象。但是,类可以表明它对其早期版本保持兼容,要想这样做,就必须首先获得这个类的早期版本的指纹。我们可以使用JDK中的单机程序serialver来获得这个数字,例如,运行下面的命令
image

如果在运行serialver程序时添加-show选项,那么这个程序就会产生下面的图形化对话框(参见图2-7)。

image

这个类的所有较新的版本都必须把serialVersionUID常量定义为与最初版本的指纹相同。
image

如果一个类具有名为serialVersionUID的静态数据成员,它就不再需要人工地计算其指纹,而只需直接使用这个值。
一旦这个静态数据成员被置于某个类的内部,那么序列化系统就可以读入这个类的对象的不同版本。
如果这个类只有方法产生了变化,那么在读入新对象数据时是不会有任何问题的。但是,如果数据域产生了变化,那么就可能会有问题。例如,旧文件对象可能比程序中的对象具有更多或更少的数据域,或者数据域的类型可能有所不同。在这些情况中,对象输入流将尽力将流对象转换成这个类当前的版本。
对象输入流会将这个类当前版本的数据域与被序列化的版本中的数据域进行比较,当然,对象流只会考虑非瞬时和非静态的数据域。如果这两部分数据域之间名字匹配而类型不匹配,那么对象输入流不会尝试将一种类型转换成另一种类型,因为这两个对象不兼容;如果被序列化的对象具有在当前版本中所没有的数据域,那么对象输入流会忽略这些额外的数据;如果当前版本具有在被序列化的对象中所没有的数据域,那么这些新添加的域将被设置成它们的默认值(如果是对象则是null,如果是数字则为0,如果是boolean值则是false)。
下面是一个示例:假设我们已经用雇员类的最初版本(1.0)在磁盘上保存了大量的雇员记录,现在我们在Employee类中添加了称为department的数据域,从而将其演化到了2.0版本。图2-8展示了将1.0版的对象读入到使用2.0版对象的程序中的情形,可以看到department域被设置成了null。图2-9展示了相反的情况:一个使用1.0版对象的程序读入了2.0版的对象,可以看到额外的department域被忽略。
image

这种处理是安全的吗?视情况而定。丢掉数据域看起来是无害的,因为接收者仍旧拥有它知道如何处理的所有数据,但是将数据域设置为null却有可能并不那么安全。许多类都费尽心思地在其所有的构造器中将所有的数据域都初始化为非null的值,以使得其各个方法都不必去处理null数据。因此,这个问题取决于类的设计者是否能够在readObject方法中实现额外的代码去订正版本不兼容问题,或者是否能够确保所有的方法在处理null数据时都足够健壮。

相关文章
|
13天前
|
NoSQL Java 数据库连接
深入探索 Java 后台开发的核心技术
【4月更文挑战第5天】本文探讨了Java后台开发的关键技术,包括Spring框架与Spring Boot的使用,MyBatis和Hibernate的ORM选择,关系型与NoSQL数据库的适用场景,线程池与异步处理在并发中的作用,微服务架构及RESTful API设计。这些核心技术有助于开发者打造稳定、高性能的Java后台系统,适应不断发展的云计算和人工智能需求。
|
3月前
|
开发框架 Java API
最新Java基础系列课程--Day13-高级特性(二)
最新Java基础系列课程--Day13-高级特性
|
4月前
|
存储 缓存 安全
《java核心技术36讲》学习笔记-------杨晓峰(极客时间)
《java核心技术36讲》学习笔记-------杨晓峰(极客时间)
54 0
|
3月前
|
Java 程序员 API
最新Java基础系列课程--Day13-高级特性(三)
最新Java基础系列课程--Day13-高级特性
|
3月前
|
开发框架 Java 程序员
最新Java基础系列课程--Day13-高级特性(一)
最新Java基础系列课程--Day13-高级特性
|
3月前
|
Java 测试技术 API
【Java技术深入解析】「核心技术提升」最流行的Java模拟框架Mockito入门指南(Java单元测试)
还在使用 Mockito 1.x?看看 Mockito 2 有哪些新功能!Mockito 3 没有引入任何破坏性的 API 变动,但现在需要 Java 8 而不是 Mockito 2 的 Java 6。 Mockito 4 删除了过时的 API。Mockito 5 将默认 mockmaker 改为 mockito-inline,现在需要 Java 11。一次只支持一个主要版本,而且不会向旧版本回传更改内容。
56 0
【Java技术深入解析】「核心技术提升」最流行的Java模拟框架Mockito入门指南(Java单元测试)
|
4月前
|
开发框架 Java 程序员
最新Java基础系列课程--Day13-高级特性
最新Java基础系列课程--Day13-高级特性
|
4月前
|
存储 Java 编译器
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记(下)
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记
81 0
|
4月前
|
存储 自然语言处理 Java
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记(上)
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记
86 0
|
4月前
|
Oracle Java 关系型数据库
《Java 核心技术卷1 基础知识》第二章 Java 程序设计环境 笔记
《Java 核心技术卷1 基础知识》第二章 Java 程序设计环境 笔记
32 1