【问题标题】:Does the FindBugs EI_EXPOSE_REP bug only concern Date?FindBugs EI_EXPOSE_REP 错误是否只涉及日期?
【发布时间】:2012-11-20 12:23:21
【问题描述】:

Findbugs 在我的代码中报告了很多 EI_EXPOSE_REP 和 EI_EXPOSE_REP2 错误,每次我这样编写 getter 和 setter 时:

  public Date getDate() {
    return date;
  }
  public void setDate(final Date date) {
    this.date = date;
  }

我理解报告的含义,我不应该将我的对象的内部引用暴露给外界,以免它们被恶意/错误代码修改。解决方法是:

  public Date getDate() {
    return date == null ? null : date.clone();
  }
  public void setDate(Date date) {
    this.date = date == null ? null : date.clone();
  }

我的问题不在这里。我很惊讶这份报告涉及 ALWAYS Date。为什么不是所有其他可变对象?我认为这个报告也适用于所有可变对象,不是吗?

我是否应该将此“良好实践”扩展到所有处理可变对象的访问器?

给我你的建议,谢谢

【问题讨论】:

    标签: java getter-setter findbugs accessor


    【解决方案1】:

    我当然希望这份报告涉及所有可变对象,但我怀疑 FindBugs 知道某些常见的违规者。

    我通常会小心通过 getter 暴露内部状态,例如

    public ArrayList<Trade> getTrades() {
       return trades;
    }
    

    意思

    1. 客户可能会在您的交易清单中发生变化
    2. 客户可能会更改您出于善意传递的清单

    因此有两种方法。

    1. 传递该对象的 不可变 变体(即无法更改的对象)。在上述场景中,您将获取该列表的只读副本并将其传递出去(您可能会争辩说您可以只获取一个简单的读写副本并传递它,因为它不会影响原始对象,但这是违反直觉的)
    2. 不要将对象(交易列表)传递出去,而是让拥有对象为您对该集合执行操作。这也许就是 OO 的精髓——告诉对象为你做事,而不是向他们询问信息并自己做

    类似的参数与设置器和构造器参数有关。

    请注意,您可能会发现自己在曝光时会复制大量对象以保护自己,并且可能会做很多额外的工作。这是一种谨慎使用的技术,值得了解您的客户对象是谁,以及您是否可以控制和/或信任它们。

    【讨论】:

    • 嗨,布赖恩,感谢您的回答。您究竟将什么称为“该对象的一个不可变变体”?
    • 修改了上面的答案。不可变对象是无法更改的对象。例如没有 setter、field final 等。
    【解决方案2】:

    Date 对象具有 setMonth 和其他 setter 来操作值,而大多数其他可变对象没有 setter 来更改其值(例如 Integer 没有任何 setter)。

        Case 1 :
    
        Date date =  obj.getDate();        
        date.setHours(10);
    
        Case 2 :
    
        Integer i = obj.getI();
        i = 10;
    

    Finbug 仅将案例 1 视为安全威胁。

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 2012-12-16
      • 1970-01-01
      • 2018-04-28
      • 2010-09-27
      • 1970-01-01
      • 2019-12-12
      • 1970-01-01
      • 2016-07-26
      相关资源
      最近更新 更多