首页 > 编程语言 >《Effective Java》阅读笔记-第十二章

《Effective Java》阅读笔记-第十二章

时间:2024-02-21 16:23:56浏览次数:41  
标签:Java Effective 实现 第十二章 默认 接口 序列化 Serializable

Effective Java 阅读笔记

第十二章 序列化

第 85 条 其他方法优先于 Java 本身的序列化

Java 本身的序列化漏洞过多,很容易被攻击。避免被序列化攻击的最好方式就是不要反序列化任何字节流,并且新的系统中没有任何理由使用 Java 本身的序列化。

JSON 和 Protobuf 是两种优秀的序列化方式,前者是基于文本, 后者是二进制的。

第 86 条 谨慎地实现 Serializable 接口

实现 Serializable 接口很容易,但是长期开销非常高。

  1. 一旦这个类被发布,就大大降低了“改变这个类的实现”的灵活性。实现 Serializable 接口代表这个类可以被转换成字节流,而内部私有字段和包级别变量也会被转换,因此就不能轻易修改实现。
  2. 增加了 bug 和安全漏洞出现的可能。反序列化机制就是一个“隐藏的构造器”,可以很容易的使对象关系遭到破坏。
  3. 随着类的更新,相关测试负担会增加。比如需要检查是否可以“在新版本中序列化一个实例,在旧版本中反序列化”。这种类越多,发行的版本越多,需要进行的测试也就越多。

因此实现 Serializable 接口不能轻易做决定。

为了继承而设计的类应尽可能少的实现 Serializable,接口也是一样。

内部类(非静态成员类)不应该实现 Serializable 接口,因为这种类包含一个指向外围实例的引用,其序列化方式是不清楚的。
静态成员类可以实现。

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

如果事先没有认真考虑默认的序列化形式是否合适,那就不要贸然使用默认的方式。一旦使用了默认的序列化形式,这个类就会永远被它所牵制。

如果一个对象的物理表示等同于它的逻辑内容,可能会适合用默认的序列化形式(比如 Entity、DTO等)。

即使默认的序列化方式合适,一个也需要提供一个 readObject 的方法以保证约束关系和安全性。

当一个对象的物理表示和逻辑有实质性区别时,默认序列化有以下 4 个缺点:

  1. 使这个类的导出 API 永远束缚在内部实现上。(修改内部实现会导致反序列化失败)
  2. 消耗过多空间。默认的序列化记录了非常多的信息。
  3. 消耗过多时间。序列化逻辑不了解对象图的拓扑关系,所以必须要经历一个昂贵的图遍历过程。(说白了就是慢)
  4. 会引起栈溢出。对象图的遍历执行的方式是递归,很容易栈溢出。

第 88 条 保护性的编写 readObject 方法

第 89 条 对实例的控制,枚举类型优先于 readResolve

第 90 条 考虑使用序列化代理替换序列化实例


序列化这张没啥意思,主要就是说尽量别用 Java 自身的序列化。

标签:Java,Effective,实现,第十二章,默认,接口,序列化,Serializable
From: https://www.cnblogs.com/code-blog/p/18025542

相关文章

  • java类初始化及代码块加载顺序连根拔起
    说明相信很多人对于java中父子继承关系中,子类实例化调用过程中,代码块的执行顺序都容易忘记或搞混,尤其是java初级笔试题或面试题最容易出这类题目,让人恨得牙痒痒!!!本文就一次性将其连根铲除,看完你就不会有这个烦恼了,哈哈。先引用一下骨灰级大作《Java编程思想》的复用章节Java......
  • 一键脚本破解最新版 idea 步骤,开启学习java 之旅,好好好
    效果:步骤1、idea安装:直接在官网下载最新idea-2022.2.3.dwg(:官网地址,然后根据安装引导一步一步完成安装即可,完成后打开idea看到如下效果表示idea安装成功!如图发现idea需要注册!这里我们先不管,直接关闭idea准备激活!步骤2、下载最新的破解包https://pan.baidu.com/s/1iQby9......
  • Hutool - 简化Java编程的法宝,让工作更高效
    一、在项目的pom.xml的dependencies中加入以下内容:<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.0.7</version></dependency>非Maven项目的话就自己百度下载一下jar包,导入即可。二、StrUtil看这里名字也应该明白了,......
  • 承前启后,Java对象内存布局和对象头
    承前启后,Java对象内存布局和对象头大家好,我是小高先生。在我之前的一篇文章《并发编程防御装-锁(基础版)》中,我简要介绍了锁的基础知识,并解释了为什么Java中的任何对象都可以作为锁。在那里,我提到了对象头中有一个指向ObjectMonitor的指针,但没有深入探讨Java对象的内存结构。本文将......
  • Java的配置
    环境变量配置找到配置的位置右击此电脑-->属性-->高级系统设置-->环境变量-->系统变量配置Path环境变量(必须配置的)(目的:为了可以在任意目录下找到javac和java命令)方式1:直接在Path变量中添加jdk的bin目录的完整路径系统变量-->Path-->新建-->D:\soft\java\jdk\bin方式2:(推荐......
  • java练习2(四位数字进行加密)
    packagecom.shujia.zuoye;importjava.util.Scanner;/*某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。结果如图所示。*/publicclass加密......
  • java练习1(求圆的周长与面积)
    packagecom.shujia.zuoye;importjava.util.Scanner;/*输入圆形半径,求圆形的周长和圆形的面积,并将结果输出。/publicclass求圆的面积{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);System.out.println("请输入圆的半径:");doubler=s......
  • 在阿里云部署javaspringboot项目
    记住自己服务器的账号密码配置安全组  用xshell连接服务器(xftp同理) 到官网去下载jdk的Linux版本,官网地址:https://www.oracle.com/technetwork/java/javase/downloads 安装JDK我自己用的是jdk21,下载完毕后用xftp传到服务器上(解压一下)#tar-zxvf压缩包.tar.......
  • java~Date和LocalDateTime及Instant的使用场景
    在Java中,LocalDateTime、Date和Instant分别代表了不同的日期时间类型,它们之间有一些区别和适用场景。Date:java.util.Date是Java早期的日期时间类,它包含了日期和时间信息,但是在设计上存在一些问题,因此并不推荐在新的代码中使用。Date类存在线程安全性问题,同时它的......
  • Java基本语法
    Java基本语法1.1注释1.单行注释//2.多行注释/**/3.文档注释/***/1.2标识符和关键字Java所有的组成部分都需要名字。类名,变量名,方法名都被称为标识符。关键字:所有标识符都应该以字母,$,下划线开头。首字母之后可以是字母,$,__或者数字任何字符组合。关键......