2010-04-09 245 views
9

我在这里一无所知......的FindBugs - 如何解决EQ_COMPARETO_USE_OBJECT_EQUALS

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

我不知道如何解决这一。

回答

13

这个错误意味着你没有覆盖在ForeignKeyConstraintequals(并由此继承equalsObject),所以下面是不正确的(从compareTo的Javadoc):

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

要解决的FindBugs的检查,覆盖equals - 和hashCode - 如果它是有道理这是一般的情况(或排除这个类和文档类违反使用建议记下此条件检查)。

2

您是否尝试过重写equals方法以及SqlFixer.ForeignKeyConstraint?

我相信警告的基础是,如定义中所述,如果您重写compareTo而不是equals,则会发生奇怪的事情。

欲了解更多信息结账Joshua Bloch's Effective Java, 2nd Edition。第12项更深入地介绍了实施Comparable的细节和一些需要注意的事项。

4

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

“通常,compareTo的值应该返回零,当且仅当equals返回true时,如果违反,那么奇怪的和不可预知的故障将发生在诸如PriorityQueue的类中。 “

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

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

4

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

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

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

0

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