当前位置: 首页 > 图灵资讯 > 技术篇> 项目 必要时制作防御性副本

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

来源:图灵教育
时间:2024-09-04 20:19:19

“假设你的客户会尽力破坏他们的不变量,你应该进行防御性编程。”

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 存储对象时,必须考虑对象以后是否可以修改。

内部部件返回:

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

使用不可变对象:

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

成本及替代方案:

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

结论:

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

书中的示例:

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

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

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

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

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

以上是项目 必要时制作防御副本的详细内容,请关注图灵教育的其他相关文章!