FindBugs - 如何解决EQ_COMPARETO_USE_OBJECT_EQUALS

时间:2010-04-09 16:15:25

标签: java findbugs compareto

我在这里一无所知......

 1: private static class ForeignKeyConstraint implements Comparable<ForeignKeyConstraint> {
 2: String tableName;
 3: String fkFieldName;
 4: 
 5: public int compareTo(ForeignKeyConstraint o) {
 6:    if (this.tableName.compareTo(o.tableName) == 0) {
 7:            return this.fkFieldName.compareTo(o.fkFieldName);
 8:        }
 9:        return this.tableName.compareTo(o.tableName);
10:    }
11: }

在第6行,我来自FindBugs:Bug: net.blabla.SqlFixer$ForeignKeyConstraint defines compareTo(SqlFixer$ForeignKeyConstraint) and uses Object.equals()

Link to definition

我不知道如何纠正这个问题。

5 个答案:

答案 0 :(得分:15)

此错误意味着您没有覆盖equals中的ForeignKeyConstraint(从而继承equals中的Object),因此以下情况属实(来自javadoc) of compareTo):

  

强烈建议,(x.compareTo(y)==0) == (x.equals(y))并非严格要求。一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:此类具有与equals不一致的自然顺序。”

要修复FindBugs检查,请覆盖equals - 和hashCode - 如果通常情况有意义(或排除对此类和文档的检查,表明您的类违反了此条件,请使用建议的说明)。

答案 1 :(得分:4)

您可以通过实现equals()方法来解决它。请参阅FindBugs定义:

“通常,当且仅当equals返回true时,compareTo的值才应返回零。如果违反此规则,则会在诸如PriorityQueue之类的类中发生奇怪且不可预测的失败。”

“强烈建议,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))。”

另一个例子是TreeSet。它通过调用compareTo来实现相等性检查,并且与equals不一致的compareTo实现使得TreeSet违反了Set接口的约定,这可能导致程序故障。

答案 2 :(得分:4)

它告诉你,compareTo()和equals()有可能不同意。他们应该,实际上,从不反对。

equals()方法是从java.lang.Object继承的,它默认检查两个对象是否是相同的 instance 。您的compareTo方法是比较对象基于tableName和fkFieldName。所以你可能会发现自己处于这样一种情况:compareTo声明两个对象是相同的(因为tableName和fkFieldName匹配),但是等于状态它们是不同的(因为它们是不同的实例)。

有一些java API依赖于compareTo和equals是一致的;这是java语言的一部分,被认为是核心语言契约。理想情况下,实现一个equals(和hashcode)方法,以根据tableName和fkFieldName检查相等性。

答案 3 :(得分:2)

您是否尝试过在SqlFixer.ForeignKeyConstraint中覆盖equals方法?

我认为警告的基础是,如定义中所述,如果覆盖compareTo而不是equals,则会发生奇怪的事情。

有关详细信息,请查看Joshua Bloch's Effective Java, 2nd Edition。第12项更深入地介绍了实施Comparable的内容和一些需要注意的事项。

答案 4 :(得分:0)

Findbugs很满意:

public int compareTo(ForeignKeyConstraint o) {
    if (this.equals(o)) {
        return 0;
    } else if (this.tableName.equals(o.tableName)) {
        // fkFieldName must be different
        return this.fkFieldName.compareTo(o.fkFieldName);
    } else {
        // tableName must be different
        return this.tableName.compareTo(o.tableName);
    }
}

@Override
public equals() {
  ...
}

@Override
public int hashCode() {
  ...
}