《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.4.4 序列化单例和类型安全的枚举

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

2.4.4 序列化单例和类型安全的枚举

在序列化和反序列化时,如果目标对象是唯一的,那么你必须加倍当心,这通常会在实现单例和类型安全的枚举时发生。
如果你使用Java语言的enum结构,那么你就不必担心序列化,它能够正常工作。但是,假设你在维护遗留代码,其中包含下面这样的枚举类型:
image
image

这种风格在枚举被添加到Java语言中之前是很普遍的。注意,其构造器是私有的。因此,不可能创建出超出Orientation.HORIZONTAL和Orientation.VERTICAL之外的对象。特别是,你可以使用==操作符来测试对象的等同性:

当类型安全的枚举实现Serializable接口时,你必须牢记存在着一种重要的变化,此时,默认的序列化机制是不适用的。假设我们写出一个Orientation类型的值,并再次将其读回:

image

将失败。事实上,saved的值是Orientation类型的一个全新的对象,它与任何预定义的常量都不等同。即使构造器是私有的,序列化机制也可以创建新的对象!
为了解决这个问题,你需要定义另外一种称为readResolve的特殊序列化方法。如果定义了readResolve方法,在对象被序列化之后就会调用它。它必须返回一个对象,而该对象之后会成为readObject的返回值。在上面的情况中,readResolve方法将检查value域并返回恰当的枚举常量:
image

请记住向遗留代码中所有类型安全的枚举以及向所有支持单例设计模式的类中添加readResolve方法。

相关文章
|
25天前
|
Java
【Java基础面试五】、 int类型的数据范围是多少?
这篇文章回答了Java中`int`类型数据的范围是-2^31到2^31-1,并提供了其他基本数据类型的内存占用和数值范围信息。
【Java基础面试五】、 int类型的数据范围是多少?
|
13天前
|
自然语言处理 算法 Java
Java如何判断两句话的相似度类型MySQL的match
【9月更文挑战第1天】Java如何判断两句话的相似度类型MySQL的match
17 2
|
19天前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之dal层中的mapper数据源类型进行组织的问题如何解决
Java应用结构规范问题之dal层中的mapper数据源类型进行组织的问题如何解决
|
24天前
|
前端开发 Java 数据库
Java系列之 Long类型返回前端精度丢失
这篇文章讨论了Java后端实体类中Long类型数据在传递给前端时出现的精度丢失问题,并提供了通过在实体类字段上添加`@JsonSerialize(using = ToStringSerializer.class)`注解来确保精度的解决方法。
|
25天前
|
Java
Java枚举使用的基本案例
这篇文章是关于Java枚举的基本使用,通过一个指令下发的代码案例,展示了如何定义枚举、使用枚举以及如何通过枚举实现指令的匹配和处理。
|
17天前
|
安全 Java 编译器
java枚举
java枚举
13 0
|
20天前
|
开发工具 数据安全/隐私保护
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
|
26天前
|
Java
成功解决:java: 找不到符号 符号: 方法 getSort() 位置: 类型为com.atguigu.gulimall.product.entity.CategoryEntity的变量 menu1
这篇文章讨论了Java中遇到的一个常见错误:"java: 找不到符号 符号: 方法 getSort() 位置: 类型为com.atguigu.gulimall.product.entity.CategoryEntity的变量 menu1",即在尝试调用一个不存在的方法时出现的问题,并提供了相应的解决方法。
|
24天前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 开发框架 .NET
解锁SqlSugar新境界:利用Serialize.Linq实现Lambda表达式灵活序列化与反序列化,赋能动态数据查询新高度!
【8月更文挑战第3天】随着软件开发复杂度提升,数据查询的灵活性变得至关重要。SqlSugar作为一款轻量级、高性能的.NET ORM框架,简化了数据库操作。但在需要跨服务共享查询逻辑时,直接传递Lambda表达式不可行。这时,Serialize.Linq库大显身手,能将Linq表达式序列化为字符串,实现在不同服务间传输查询逻辑。结合使用SqlSugar和Serialize.Linq,不仅能够保持代码清晰,还能实现复杂的动态查询逻辑,极大地增强了应用程序的灵活性和可扩展性。
73 2