2014-04-02 90 views
3

我有一個方法需要兩個Doublesab(注意大寫「D」)並計算差異。如果只有一個參數是null,結果應爲999999,否則返回兩個數字之間的差值。FindBugs:雙重引用的可疑比較

以下(工作)代碼在FindBugs中給我一個「可怕的」警告,我通常會盡量避免代碼中出現高排名的警告。但是,我認爲代碼既簡短又可讀,而我認爲的所有其他內容都使其不易讀。恕我直言,使用==這個的情況下是完全正確的。

public double foo(Double a, Double b) { 
    return a == b ? 0 : (a != null && b != null) ? b - a : 999999; 
} 

而對於該行的FindBugs的報告:

缺陷:在 Main.foo雙引用的可疑的比較(雙,雙)

此方法會比較使用所述兩個參考值==或!=運算符, 其中,使用equals()方法比較此類型實例的正確方法通常是 。有可能創建不同的實例 ,它們是相同的,但不會比較爲==,因爲它們是不同的 對象。這通常應不通過 參考進行比較的種類的實例是java.lang.Integer中,java.lang.Float中等

信心:高,等級:最可怕的(1)圖樣:RC_REF_COMPARISON類型: RC,類別:正確性(正確)

任何想法如何重寫這個代碼乾淨,簡單沒有警告?

+0

沒有直接關係,但像PMD其他代碼檢查工具會抱怨 「幻數」 你有沒有(999999) ,因爲它不清楚它的含義,如果你不得不在其他地方使用它,很容易輸入錯誤(Harmlezz的答案爲9999,例如:-))。更好地使用像DIFFERENCE_WHEN_NULL或MAX_DIFFERENCE這樣有意義的名稱的常量 –

+0

是的,這當然是正確的。 – Axel

+0

想了一會兒,我想你的代碼是正確的,如果你希望'foo(null,null)'產生'0.0d'的結果。通常,使用'=='比較'Double'對象表示程序員錯誤('=='比較引用,而不是'Double'的值!)。所以你可能會忽略FindBugs這個特殊情況的警告。 –

回答

3

我建議更多的步驟做同樣的,易維護,從長遠來看

public double foo(Double a, Double b) { 

    //as per Marco suggestion. but not sure OP wants the same. 
    if(a == null && b == null){ 
      return 0; 
    } 
    //END 
    if(a == null || b == null){ 
      return 999999; 
    }  
    return b-a; //will return 0 if they are equal. no extra checks required 
} 
+2

基於最初的代碼,似乎比較兩個'null's應該產生'0'而不是'999999' ... – Marco13

+0

@ Marco13,反正更新代碼 – Reddy

+0

的確,這可能被認爲比我的答案更簡潔對於這種情況。爲了證明我的兩步法:我仍然想知道像'd(null,b)= -Infinity'和'd(a,null)= + Infinity'這樣的東西可能不太合適,但那是隻有提問者可以決定...... – Marco13

2

==檢查兩個引用是否指向同一個對象。但是,您必須檢查兩者是否具有相同的值。因此,使用.equals()方法

public double foo(Double a, Double b) { 
    return (a != null && a.equals(b)) ? 0 : (a != null && b != null) ? b - a : 999999; 
} 
+3

這可能會在'a.equals(' – Harmlezz

+0

@Harmlezz:Corrected。 –

+1

@ Harmlezz and a == b? – Boris

2

...以及其他一切我只是覺得使得它的可讀性

取決於你是否喜歡在可讀性正確性與否,你可以考慮

public double foo(Double a, Double b) 
{ 
    if (a == null) 
    { 
     if (b == null) 
     { 
      return 0; 
     } 
     return 999999; 
    } 
    if (b == null) 
    { 
     return 999999; 
    } 
    return b - a; 
} 

BTW:This 999999看起來很可疑。也許這應該是Double.POSITIVE_INFINITYDouble.MAX_VALUE左右,但確定取決於預期用途。

+0

你不需要太多重複的代碼。檢查我的解決方案簡單而直接的 – Reddy

+0

正如在你的回答的評論中提到的那樣:這取決於比較兩個'null'值是否應該是'0'或'999999'(這並不意味着代碼不能寫*更短,但我認爲我的解決方案清晰易懂,我不喜歡嵌套的三元'':'陳述和其他體操,代碼應該像散文一樣閱讀 – Marco13

1

怎麼樣這樣:

public static void main(String[] args) { 
    print(null, null); 
    print(5.0, null); 
    print(null, 2.0); 
    print(5.0, 2.0); 
} 

public static void print(Double a, Double b) { 
    System.out.printf("a=%f, b=%f result=%f\n", a, b, foo(a, b)); 
} 

public static double foo(Double a, Double b) { 
    return a == null 
      ? b == null ? 0 : 9999 
      : b == null ? 9999 : b - a; 
} 

OUTPUT:

a=null,  b=null  result=0.000000 
a=5.000000, b=null  result=9999.000000 
a=null,  b=2.000000 result=9999.000000 
a=5.000000, b=2.000000 result=-3.000000 
+0

我想我需要一些括號來表達這個...... – Axel