2012-10-13 267 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”)后才可用。 –