2012-10-13 266 views
1

我最近在eclipse中設置了查找錯誤,以查看它生成的報告。我已將所有設置設置爲儘可能敏感。如果我創建了一個寫入文件的小應用程序,並且不關閉流,那麼它就會啓動它,這很好。查找錯誤 - 找不到錯誤

然而,使用已寫入,我們沒有有幾個錯誤的項目,特別是在輸出中,我們得到完全沒有錯誤(在發現漏洞方面)

我想知道是否有人可以通過他們的版本運行它,並報告我是否可能找到錯誤設置的錯誤,或者實際上是否可以找到沒有錯誤?

import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 


public class SpellUtil { 

    private final static String teenSpelling[] = {"Zero", "One", "Two", "Three", 
     "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", 
     "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", 
     "Seventeen", "Eighteen", "Nineteen"}; 

    private final static String centSpelling[] = {"Twenty", "Thirty", "Forty", 
     "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; 

    private final static String suffixSpelling[] = { 
     "", // Dummy! no level 0 (added for nicer indexing in code) 
     "", // Nothing for level 1 
     " Thousand, ", " Million, ", " Billion, ", " Trillion, ", " Quadrillion, ", 
     " Quintillion, "}; 



    public static String spell(int number) { 

     int rem, placeIndicator = 1; 
     boolean isNegative = false; 
     List<String> spelling = new ArrayList<String>(); 

     if (number < 0) { 
      isNegative = true; 
      number = Math.abs(number); 
     } 

     while (number > 0) { 
      rem = number % 1000; 
      number = number/1000; 

      spelling.add(suffixSpelling[placeIndicator]); 

      try { 
       spelling.add(spellBelow1000(rem)); 
      } catch (SpellingException e) { 
       System.out.println(e.getMessage()); 
      } 

      placeIndicator++; 
     } 

     StringBuilder sb = new StringBuilder(); 
     if (isNegative) sb.append("Minus "); 
     for (int i = spelling.size() - 1; i >= 0; i--) { 
      sb.append(spelling.get(i)); 
     } 

     return sb.toString(); 
    } 

    private static String spellBelow1000(int number) throws SpellingException { 

     if (number < 0 || number >= 1000) 
      throw new SpellingException("Expecting a number between 0 and 999: " + number); 

     if (number < 20) { 
      // if number is a teen, 
      // find it in teen table and return its equivalent text (word). 
      return teenSpelling[number]; 
     } else if (number < 100) { 
      // otherwise, if it is a cent, 
      // find the most (div) and least (rem) significant digits (MSD/LSD) 
      int div = (int) number/10; 
      int rem = (int) number % 10; 

      if (rem == 0) { 
       // if LSD is zero, return the cent key word directly (like 
       // fifty). 
       return centSpelling[div-2]; 
      } else { 
       // otherwise, return the text as cent-teen (like fifty-one) 
       return centSpelling[div-2] + "-" + teenSpelling[rem]; 
      } 
     } else { 
      // otherwise, it is a mil; 
      // find it's MSD and remaining cent. 
      int div = number/100; 
      int rem = (int) number % 100; // TODO will findbugs detect unnecessary (int)? 

      // Prepare the mil prefix: 
      String milText = teenSpelling[div] + " Hundred"; 

      // decide whether to append the cent tail or not. 
      if (rem == 0) { 
       // if it does have a non-zero cent, that's it. 
       // return the mil prefix, for example three hundred: 
       return milText; 
      } else { 
       // otherwise, spell the cent and append it to mil prefix. 
       // (now, rem is a cent). 
       // For example, three Hundred and Sixty-Four: 
       return milText + " and " + spellBelow1000(rem); 
      } 
     } 
    } 
} 
+1

它應該找到哪個特定的錯誤,但沒有?你覺得FindBugs會發現你的程序可能有什麼錯誤嗎? –

+0

不 - 我只是假設它至少會拋出一些警告或者什麼 – Biscuit128

+0

而你認爲那個bug是哪裏的? – exexzian

回答

2

你期望找到一個bug在這一行:

int rem = (int) number % 100; // TODO will findbugs detect unnecessary (int)? 

是錯誤的,因爲一個%操作的結果不是一般的整數。

CC++,餘數運算符只接受積分操作數,但在Java中,它也接受浮點操作數。這意味着諸如double x = 8.2 % 4;之類的語句在Java中非常有效,結果可能是非整數值。 (在這種情況下爲0.1999999999999993

請參閱Java語言規範here

+0

當'number'和'100'都是'int'類型時,結果怎麼可能不是'int'? –

+0

'%'操作的結果通常不是整數**。如果兩個操作數的類型都是'int',結果將是'int'類型。 – RGO

+0

FindBugs在這種情況下知道操作數的類型。由於編譯器也是如此,它可能會丟棄演員陣容,而FB甚至不會看到它。 –

0

findbugs做的是尋找一些常見的錯誤,可能(而且很可能會)導致意外/不想要的行爲。這些錯誤大部分是技術性的或錯誤的使用Java及其API。所有findbugs檢查的列表可以找到here換句話說,如果你做了一件你不想要的東西,findbugs就不會檢測到它。在你的代碼中,我看不到任何findbugs會檢測到的東西。您在評論中提到的不必要的轉換不是findbugs規則,因爲它不會更改代碼的行爲。它更像是一種風格或效率錯誤,會被類似checkstylePMD的工具檢測到。

1

你似乎有findbugs配置問題。我建議通過Sonar使用Findbugs。配置起來要容易得多,你可以得到checkstyle,pmd和一個管理和解決違規的系統。

Sonar findbugs page

1

我覺得現在的問題是,你誤會了findBUGs做什麼以及它能力。

基本上,FindBugs解析每個類以生成一個分析樹 - 一個內存中的程序結構表示。然後嘗試在樹中找到與代表不正確或可疑編程的已知模式相匹配的地方。例如:

if (someString == "42") { 
     .... 
    } 

FindBugs的將最有可能告訴你,這裏比較使用「==」操作字符串是錯誤的。它所做的是通過類來查看運算符爲'=='的任何表達式節點,並且其中一個或兩個操作數都是String。它會重複這個程序,以處理大量已被編程爲檢測和報告的模式。有些會比這個更復雜,但基本上,FindBug只是做結構模式匹配的一種形式。

FindBugs不能做什麼也不能做的是理解你的程序實際上應該做什麼。因此,例如:

public boolean isOdd(int arg) { 
     return (arg % 2) == 0; 
    } 

這顯然是不正確的人誰明白簡單的數學......但FindBugs的不會注意到它。這是因爲FindBugs不知道該方法實際上應該做什麼。此外,它不能進行基本的語義分析,因爲它需要弄清楚代碼沒有實現數學。


的原因,我這樣做是因爲我需要做的發現bug的介紹,我需要一個應用程序生成的一些錯誤,以顯示它是如何工作的。

也許你需要騙了一下:

  • 閱讀FindBugs的文檔來了解的事情,這是能夠找到的。
  • 用FindBugs爲您找到的bug編寫一些「玩具」應用程序。

這也是值得的,包括你知道它不會找到的例子...以便您可以解釋Findbugs的侷限性。

+0

另外,FindBugs的一些功能只有在您向代碼中添加註釋(例如「@ Nonnull」和「@ ThreadSafe」)後纔可用。 –