首页  >  文章  >  Java  >  项目 必要时制作防御性副本

项目 必要时制作防御性副本

王林
王林原创
2024-08-30 08:32:40690浏览

“你应该进行防御性编程,假设你的类的客户将尽最大努力破坏其不变量”

Java 作为一种安全语言:

  • Java 可以防止 C/C++ 中常见的内存错误,但不能完全隔离类与其他类之间不必要的交互。
  • 假设类的客户端可能试图违反其不变量,则需要进行防御性编程。

不可变类和安全性:

  • 类“Period”的示例,它看起来不可变,但可能由于日期等对象的可变性而被损坏。
  • 解决方案:在构造函数中接收可变参数时,制作可变参数的防御性副本。
public Period(Date start, Date end) {
    this.start = new Date(start.getTime()); // Cópia defensiva
    this.end = new Date(end.getTime());
    if (this.start.compareTo(this.end) > 0)
        throw new IllegalArgumentException(start + " after " + end);
}

构建器中的防御副本:

  • 在验证参数之前必须制作防御副本,以避免漏洞(例如 TOCTOU 攻击)。
  • 避免使用clone()来保护潜在不受信任的对象的副本,首选静态构造函数或工厂方法。

吸气剂和可变性:

  • 问题:Getter 可以暴露可变的内部组件,从而允许外部突变。
  • 解决方案:Getter 应该返回可变对象的防御性副本。
public Date getStart() {
    return new Date(start.getTime()); // Cópia defensiva
}

应用于可变类:

  • 防御性复制也适用于存储对客户端提供的可变对象的引用的可变类。
  • 示例:在 Set 或 Map 中存储对象时,必须考虑该对象以后是否可以修改。

内部组件返回:

  • 返回可变内部时,请考虑返回防御副本或不可变视图。

使用不可变对象:

  • 只要有可能,就使用不可变对象作为内部组件,以避免需要防御性副本。

成本和替代方案:

  • 防御性副本会影响性能;替代方案包括依赖文档或明确的使用协议。
  • 在显式转移控制的情况下,例如在设计模式中(例如包装器),可以省去防御性副本。

结论:

  • 使用防御性副本来保护类的完整性,除非成本不切实际或建立了相互信任并且需要清晰的文档。

书中的示例:

Item  Faça cópias defensivas quando necessário

Item  Faça cópias defensivas quando necessário

Item  Faça cópias defensivas quando necessário

Item  Faça cópias defensivas quando necessário

Item  Faça cópias defensivas quando necessário

以上是项目 必要时制作防御性副本的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn