FindBugs – 如何解决EQ_COMPARETO_USE_OBJECT_EQUALS

我在这里一无所知……

1: private static class ForeignKeyConstraint implements Comparable { 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()

链接到定义

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

这个错误意味着你没有覆盖ForeignKeyConstraintequals (从而从Objectinheritanceequals ),所以以下不是真的(来自compareTo的javadoc):

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

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

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

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

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

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

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

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

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

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

我相信警告的基础是,如定义中所述,如果你覆盖compareTo而不是equals,可能会发生奇怪的事情。

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

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() { ... }