FindBugs有争议的描述

时间:2010-03-22 02:09:55

标签: java equals findbugs

我理解错了,还是说错了?

  

等于检查不兼容   操作数   (EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS)

     

这个等于方法正在检查   如果论点有些不相容   类型(即,既不是一个类   超类型和类的子类型   定义equals方法)。对于   例如,Foo类可能有一个   等于看起来像的方法:

public boolean equals(Object o) {
  if (o instanceof Foo)
    return name.equals(((Foo)o).name);
  else if (o instanceof String)
    return name.equals(o);
  else return false;
  

这被认为是不好的做法,因为它很难   实现一个等于的方法   对称和传递。没有   那些属性,非常意外   行为是可能的。

来自:http://findbugs.sourceforge.net/bugDescriptions.html#EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS

描述说Foo类可能有一个这样的equals方法,之后它说“这被认为是不好的做法”。我没有得到“正确的方式”..

以下方法应该如何正确?

@Override
public boolean equals(Object obj) {
if (obj instanceof DefaultTableModel)
    return model.equals((DefaultTableModel)obj);
else
    return false;
}

3 个答案:

答案 0 :(得分:4)

当FindBugs描述说某种情况“可能就是这种情况”时,他们并不是说这是一种可接受的做法,而是一种假设的情况,这会导致有问题的警告。

您不应该说您的对象等于某些DefaultTableModel,因为无法强制执行该关系的反身性。这意味着给定

DefaultTableModel dtm = new DefaultTableModel(...);
YourObject foo = new YourObject(dtm);
foo.equals(dtm); // true
dtm.equals(foo); // false!

答案 1 :(得分:3)

该方法的第一个版本(FindBugs抱怨)的问题是非对称

如果你有ff.equals("someName")的Foo对象true,那么对称性表明"someName".equals(f)也应该是true。但是你无法实现这一点:"someName".equals(...)将为任何不是String的参数返回false

该方法的第二个版本也是错误的,因为您说Foo实例可以等于DefaultTableModel实例...而不是另一个Foo实例。这意味着Foo实例不能与自身相等,因此equals 非反身。此外,尚不清楚model标识符是什么......

答案 2 :(得分:0)

您实施的不寻常部分是将字段“模型”与完整的对象“obj”进行比较。通常,在检查到自己是同一个类或子类之后,应该将self的每个字段与另一个对象的每个字段进行比较。