8

最近我处理了关于暴露内部状态的 FindBugs 警告,即当返回对数组的引用而不是返回数组的副本时。我创建了一些模板以使转换该代码更容易。

您创建了哪一个来支持防御性编程并希望与 SO 人群分享?

到目前为止我创建的模板(作为示例):

创建数组的副本以从方法返回:

final ${type}[] ${result} = new ${type}[ ${array}.length ];
System.arraycopy( ${array} , 0 , ${result} , 0 , ${array}.length );

克隆一个对象:

(${o}!= null?(${type})${o}.clone():null)
4

2 回答 2

3

我喜欢将“更安全”的 equals() 定义作为模板:

 /**
 * Implement equals based on ${cursor}. <br />
 * See {@link #compareTo(Object) compareTo}
 * @see java.lang.Object#equals(java.lang.Object)
 */
public boolean equals(final Object anObject)
{
    boolean res = false;
    if(anObject == null) { return false; }
    if(anObject == this) { return true; }
    if(anObject.getClass() == this.getClass())
    {
        res = this.compareTo(anObject) == 0;
    }
    return res;
}

为了确保始终避免Eq: equals 方法覆盖超类中的 equals 并且可能不是对称的( EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC),其中:

此类定义了一个 equals 方法,该方法覆盖了超类中的 equals 方法。两种equals方法方法都使用instanceof来判断两个对象是否相等。

这充满了危险,因为 equals 方法是对称的(换句话说,a.equals(b) == b.equals(a))很重要。
如果B是 的子类型A, 和A的 equals 方法检查参数是否为instanceof A, 而 B 的 equals 方法检查参数是否为instanceof B, 很可能这些方法定义的等价关系不是对称的。


这仅适用于实现的类Comparable并允许:

  • equals 的实现总是相同的;
  • 所有比较逻辑仅位于一个位置(compareTo()函数);
  • 遵守Comparable#compareTo()要求确保这一点的 javadoc (x.compareTo(y)==0) == (x.equals(y))(强烈推荐,但并非严格要求)。
于 2008-12-17T12:42:12.660 回答
2

不是模板,但我使用array.clone()而不是System.arraycopy(). 这有什么问题吗?

编辑:我在实现装饰器时使用的模板,特别是对于具有许多方法的接口:

wrapped.${enclosing_method}(${enclosing_method_arguments})

它通过将调用委托给包装实例来生成当前方法的实现,从而防止复制/粘贴错误。

于 2008-12-17T12:33:49.277 回答