12

我这里一无所知...

 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()

链接到定义

我不知道如何纠正这个。

4

5 回答 5

17

此错误意味着您没有覆盖equalsForeignKeyConstraint并因此继承equalsfrom Object),因此以下内容不正确(来自 javadoc 的compareTo):

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

要修复 FindBugs 检查,请覆盖equals- 和hashCode- 如果通常情况下有意义(或排除对此类的检查并使用建议的注释记录您的类违反此条件)。

于 2010-04-09T16:30:56.093 回答
6

它告诉你 compareTo() 和 equals() 有可能不同意。他们应该,真的,永远不要不同意。

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

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

于 2010-04-09T16:32:26.573 回答
4

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

“一般来说,当且仅当equals返回true时,compareTo的值才应该返回零。如果违反这一点,就会在PriorityQueue等类中发生奇怪且不可预知的故障。”

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

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

于 2010-04-09T16:31:38.563 回答
2

您是否尝试过在 SqlFixer.ForeignKeyConstraint 中重写 equals 方法?

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

有关更多信息,请查看Joshua Bloch 的 Effective Java,第 2 版。第 12 项更深入地介绍了实现 Comparable 的来龙去脉以及需要注意的一些事项。

于 2010-04-09T16:31:24.833 回答
1

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() {
  ...
}
于 2011-09-11T14:12:42.037 回答