6

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。为什么不是所有其他可变对象?我认为这个报告也适用于所有可变对象,不是吗?

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

给我你的建议,谢谢

4

2 回答 2

3

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

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

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

方法

  1. 客户可能会接触到您的交易清单的变化
  2. 客户可能会更改您善意传递的清单

因此,有两种方法。

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

类似的参数与 setter 和构造函数参数有关。

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

于 2012-11-20T12:27:29.623 回答
1

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

    Case 1 :

    Date date =  obj.getDate();        
    date.setHours(10);

    Case 2 :

    Integer i = obj.getI();
    i = 10;

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

于 2013-06-04T12:31:39.583 回答