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的主要内容,如果未能解决你的问题,请参考以下文章

如何抑制字段或局部变量的 FindBugs 警告?

项目管理_FindBugs的使用

有没有办法忽略单个 FindBugs 警告?

如何删除 Findbugs 的“污点”“查找安全漏洞”

Maven Findbugs 插件 - 如何在测试类上运行 findbug

如何从 Sonar 导出 FindBugs/PMD/Checkstyle 规则并导入 Netbeans