【问题标题】:FindBugs - how to solve EQ_COMPARETO_USE_OBJECT_EQUALSFindBugs - 如何解决 EQ_COMPARETO_USE_OBJECT_EQUALS
【发布时间】:2011-02-06 05:34:57
【问题描述】:
我在这里一无所知...
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
我不知道如何改正。
【问题讨论】:
标签:
java
findbugs
compareto
【解决方案1】:
此错误意味着您没有在ForeignKeyConstraint 中覆盖equals(因此从Object 继承equals)所以以下不正确(来自compareTo 的javadoc):
强烈建议但不严格要求(x.compareTo(y)==0) == (x.equals(y))。一般来说,任何实现了 Comparable 接口并违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:这个类有一个与equals不一致的自然顺序。”
要修复 FindBugs 检查,请覆盖 equals - 和 hashCode - 如果通常情况下有意义(或排除对此类的检查并使用建议的注释记录您的类违反此条件)。
【解决方案3】:
你可以通过实现一个 equals() 方法来解决它。参考 FindBugs 定义:
“一般情况下,当且仅当equals返回true时,compareTo的值才应该返回零。如果违反这一点,就会在PriorityQueue等类中出现奇怪且不可预知的失败。”
“强烈建议,但不严格要求 (x.compareTo(y)==0) == (x.equals(y))。”
另一个例子是 TreeSet。它通过调用compareTo实现相等性检查,与equals不一致的compareTo实现使得TreeSet违反了Set接口的约定,可能导致程序故障。
【解决方案4】:
它告诉您 compareTo() 和 equals() 可能存在分歧。他们应该,真的,永远不要不同意。
equals() 方法继承自 java.lang.Object,默认情况下检查两个对象是否相同instance。您的 compareTo 方法是基于 tableName 和 fkFieldName 比较对象。因此,您可能会发现自己处于这样一种情况:compareTo 声明两个对象相同(因为 tableName 和 fkFieldName 匹配),但 equals 声明它们不同(因为它们是不同的实例)。
有一些 java API 依赖于 compareTo 和 equals 的一致性;这是 java 语言的一部分,被认为是核心语言契约。理想情况下,实现一个 equals(和 hashcode)方法来检查基于 tableName 和 fkFieldName 的相等性。
【解决方案5】:
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() {
...
}