2010-04-09 39 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() { 
    ... 
}