FindBugs - 如何解决 EQ_COMPARETO_USE_OBJECT_EQUALS
Posted
技术标签:
【中文标题】FindBugs - 如何解决 EQ_COMPARETO_USE_OBJECT_EQUALS【英文标题】:FindBugs - how to solve 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
我不知道如何改正。
【问题讨论】:
【参考方案1】:此错误意味着您没有在ForeignKeyConstraint
中覆盖equals
(因此从Object
继承equals
)所以以下不正确(来自compareTo
的javadoc):
强烈建议但不严格要求
(x.compareTo(y)==0) == (x.equals(y))
。一般来说,任何实现了 Comparable 接口并违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:这个类有一个与equals不一致的自然顺序。”
要修复 FindBugs 检查,请覆盖 equals
- 和 hashCode
- 如果通常情况下有意义(或排除对此类的检查并使用建议的注释记录您的类违反此条件)。
【讨论】:
【参考方案2】:您是否尝试过在 SqlFixer.ForeignKeyConstraint 中也覆盖 equals 方法?
我相信警告的基础是,如定义中所述,如果您覆盖 compareTo 而不是 equals,可能会发生奇怪的事情。
欲了解更多信息,请查看Joshua Bloch's Effective Java, 2nd Edition。第 12 条更深入地介绍了实现 Comparable 的来龙去脉以及需要注意的一些事项。
【讨论】:
【参考方案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()
...
【讨论】:
以上是关于FindBugs - 如何解决 EQ_COMPARETO_USE_OBJECT_EQUALS的主要内容,如果未能解决你的问题,请参考以下文章