Builder模式中,为什么必须在对象域而不是builder域中检查参数?

这个问题仅对于构造不可变类有意义,如果构造可变类,放在哪里都无法保障安全。

使用Builder模式构建不可变类ImmutableObj的实例imObj时,应该把字段的检查放在对象域。可以从两个角度分析:

  • 如果放在builder域(一般是Builder#build()方法中),会存在TOC攻击,即:时刻T1参数检查通过,时刻T2修改其中可变的参数,时刻T3调用构造器,则时刻T3时,参数又变得不合法了。
  • 如果放在对象域(一般是类的构造方法中),还要严格在完成所有字段的初始化之后(初始化之后就不可变了),再检查字段,从而彻底避免TOC攻击。如下:
public class ImmutableObj {
  private int[] nums;
  
  private ImmutableObj(int[] nums) {
    this.nums = nums.clone();
    // 完成所有字段的初始化后再检查字段
    checkArgs();
  }
  
  private void checkArgs() {
    if (...illegal...) {
      throw new IllegalArgumentException("Illegal nums ...: " + Arrays.toString(nums));
    }
  }
}

当然,上述表述有些绝对了:如果参数本身就是不可变的,那么任何时候检查都是可以的

PS:参数指Builder实例的成员变量,字段指ImmutableObj的成员变量。参数是相对于ImmutableObj的称法。


本文链接:Builder模式中,为什么必须在对象域而不是builder域中检查参数?
作者:猴子007
出处:https://monkeysayhi.github.io
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名及链接。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 34,790评论 18 399
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,704评论 9 118
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,665评论 19 139
  • 目录 第二章 创建和销毁对象 1 考虑用静态工厂方法替代构造器 对于代码来说, 清晰和简洁是最重要的. 代码应该被...
    高广超阅读 1,527评论 0 12
  • 1 古印度有那么一个故事,有个人想要步行穿越大陆,当时大陆满是荆棘而他光着脚。办法有两种要么光着脚与环境正面斗法,...
    留逝时光阅读 350评论 0 7

友情链接更多精彩内容