《Effective Java》知识点(11)--序列化

85. 其它方法优先于Java序列化

       Java系列化是很危险的,反系列化过程readObject可被攻击。避免系列化攻击的最佳方式是永远不要反系列化任何东西。在新编写的任何新系统中都没有理由再使用Java系列化。建议使用其它跨平台的数据表示法,如JSON或者protobuf。

       如果无法避免Java系列化,最好不要反系列化不被信任的数据。如果不能确保被反系列化是数据的安全性,应该利用Java 9中的对象反系列化过滤(可以设置白名单或黑名单),虽然不能确保阻止所有的攻击。

       不要编写可系列化的类。如果必须这么做,一定要加倍小心地试验。

86. 谨慎地实现Serializable接口

       实现Serializable接口付出的最大代价是,一旦一个类被发布,就大大降低了"改变这个类的实现"的灵活性。第二个代价是,增加了出现Bug和安全漏洞的可能性。第三个代价是,随着类发行新的版本,相关的测试负担也会增加。

       为了继承而设计的类应该尽可能少地去实现Serializable接口,用户的接口也应该尽可能少继承Seriablizable接口。内部类不应该实现Serializable接口。

87. 考虑使用自定义的序列化形式

      选择错误的序列化形式对于一个类的复杂性和性能都会有永久的负面影响。

87.1 如果事先没有认真考虑默认的序列化形式是否合适,则不要贸然接受。

        如果一个对象的物理表示法等同于它的逻辑内容,可能适合使用默认的序列化形式。

        即使确定了默认的序列化形式是合适的,通常还必须提供一个readObject方法以保证约束关系和安全性。

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

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

        b. 它会消耗过多的空间。

        c. 它会消耗过多的时间。比如昂贵的图遍历过程。

        d. 它会引起栈溢出。对对象图执行一次递归遍历,有可能引起栈溢出。

87.3 自定义序列化   

        提供readObject和writeObject。readObject方法的首要任务是调用defaultReadObject;而writeObject则是调用defaultWriteObject。这样可以不影响以后增加的非瞬时的(须系列化的)实例域,保持类版本向前或向后兼容性。

         对于散列表而言,应该自定义序列化  。接受默认的序列化形式会构成一个严重的Bug,因为JVM不保证散列码函数每次运行结果一样。

         在决定将一个域做成非瞬时的之前,请确认它的值是该对象逻辑状态的一部分。

         被标记为瞬时(transient)的域,当一个实例被反序列化时,这些值将被初始化为默认值。如果这些默认值不能被接受,则须在readObject里初始化或者第一次使用时初始化。

87.4  无论是否使用默认的序列化形式,如果在读取整个对象状态的任何其它方法上强制任何同步,则必须在对象序列化上强制这种同步。

         不管选择哪种序列化形式,都要为自己编写的每个可序列化的类声明一个显式的系列版本UID。不要修改系列版本UID,否则将会破坏类现有的已被序列化实例的兼容性。

88. 保护性地编写readObject方法

       当一个对象被反序列化的时候,对于客户端不应该拥有的对象引用,如果哪个域包含了这样的对象引用,就必须要做保护性拷贝,这是非常重要的。

        编写健壮readObject方法的原则:

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

    b. 对于任何约束条件,如果检查失败,则抛出一个InvalidObjectException异常。这些检查动作应该跟在所有的保护性拷贝之后。readObject方法必须执行构造器所要求的所有有效性检查。

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

    d. 无论是直接方式还是间接方式,都不要调用类中任何可被覆盖的方法。readObject方法相当于另一公有构造器。

89. 对于实例控制,枚举类型优先于readResolve

        将一个可序列化的实例受控的类编写成枚举,可以保证除了所声明的常量外,不会有其它实例。如果做不到,就必须提供一个readResolve方法,并确保该类的所有实例域都为基本类型,或者对象引用类型都是瞬时的。

90. 考虑用序列化代理代替序列化实例

        序列化代理模式,就是为可序列化的类设计一个私有的静态嵌套类,这个类有一个单独的构造器(参数为外围类)。这个构造器只从参数复制数据;不需要做一致性检查或保护性拷贝。序列化代理的默认序列化形式是外围类最好的序列化形式。外围类及其序列化代理都必须声明实现Serializable接口。

        序列化代理方法可以阻止伪字节流的攻击及内部域的盗用攻击。它的缺点是开销会比保护性拷贝方法的开销更大。

        序列化代理的局限:

    a. 不能与可以被客户端扩展的类相兼容。

    b. 不能与对象图中包含循环的某些类相兼容。

    当发现必须在一个不能被客户端扩展的类上编写readObject或者writeObject方法时,就应该考虑使用序列化代理模式。 

全书完结

### 回答1: 《Effective Java第三版》是由Joshua Bloch所著的一本Java编程指南。这本书是基于第二版的更新版本,目的是给Java程序员提供一些最佳实践和经验,以编写高效、可维护和可靠的Java代码。 这本书共分为15个章节,每个章节都讲解了一个与Java开发有关的重要主题。比如,章节一讲述了使用静态工厂方法代替构造器的优点,章节二则介绍了如何用Builder模式来构建复杂的对象。此外,书中还提及了Java对象的等价性、覆盖equals方法和hashCode方法、避免创建不必要的对象、使用泛型、枚举、lambda表达式等等。 《Effective Java第三版》通过具体的代码示例和清晰的解释来说明每个主题的关键概念,使读者能够更好地理解和应用。此外,书中还提供了一些实用的技巧和技术,例如避免使用原始类型、尽量使用接口而非类来定义类型等。 总的来说,这本书提供了很多实用的建议和技巧,可以帮助Java开发者写出高质量的代码。无论是初学者还是有经验的开发者,都可以从中受益匪浅。无论你是打算从头开始学习Java编程,还是已经有一定经验的开发者,这本书都是值得推荐的读物。 ### 回答2: 《Effective Java 第三版》是由Joshua Bloch 所著的一本Java编程指南,是Java程序员必读的经典之作。该书共包含90个条目,涵盖了各种Java编程的最佳实践和常见问题的解决方法。 本书分为多个部分,每个部分都侧重于一个特定的主题。作者探讨了Java编程中的各种问题和挑战,并提供了解决方案和建议。这些建议包括如何选择和使用合适的数据结构和算法,如何设计高效的类和接口,如何处理异常和错误,以及如何编写可读性强的代码等等。 《Effective Java 第三版》还关注了Java编程中的性能优化和安全性问题。作者强调了遵循Java语言规范、使用标准库、防范常见安全漏洞等重要原则。此外,本书还介绍了Java 8及其后续版本的新特性和用法,如Lambda表达式、流式编程和Optional类等。 这本书的特点之一是每个条目都独立于其他条目,可以单独阅读和理解。每个条目开头都有一个简洁的总结,让读者能够快速掌握主要观点。此外,书中还有大量的示例代码和解释,帮助读者更好地理解和运用所学知识。 总的来说,《Effective Java 第三版》是一本非常实用和全面的Java编程指南。它适用于各个层次的Java程序员,无论是初学者还是有经验的开发人员,都可以从中获得宝贵的经验和知识。无论是编写高质量的代码、优化性能还是确保安全性,这本书都是一本不可或缺的参考书籍。 ### 回答3: 《Effective Java 第3版(中文版)》是由 Joshua Bloch 所著的一本关于使用 Java 编程语言的指南书。该书是对 Java 语言的最佳实践的详尽描述,为中高级 Java 开发人员提供了许多实用的建议和技巧。 该书的主要内容包括Java 语言的优雅编程风格、类和接口的设计、Lambda 表达式和流的使用、泛型、异常和并发编程等方面的最佳实践。 在《Effective Java 第3版(中文版)》中,许多传统的 Java 开发中的陷阱、常见错误和不良习惯都得到了深入的剖析和解答。它不仅提供了可供开发人员参考的示例代码,还解释了为什么某种方式是有问题的,以及如何更好地进行改进。 该书的深度和广度非常适合正在努力提高 Java 编程技能的开发人员。它涵盖了多个关键领域,为读者提供了在实际项目中解决常见问题的方法和思路。 此外,《Effective Java 第3版(中文版)》还介绍了最新版本的一些特性和改进。例如,它详细说明了如何正确地使用 Java 8 中新增的 Lambda 表达式和流,以及如何充分利用 Java 9、10 和 11 中的新功能。 总之,这本书是 Java 开发人员必备的指南之一。通过深入理解和应用书中的实践建议,读者可以更加高效地编写、优化和维护 Java 代码。无论是想提升职业技能还是在项目中减少错误和问题,这本《Effective Java 第3版(中文版)》都是一本非常有帮助的参考书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值