`
hyshucom
  • 浏览: 808687 次
文章分类
社区版块
存档分类
最新评论

提高代码质量——使用FindBug自动Review

 
阅读更多

一、什么是FindBugs

FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比发现代码中可能存在的Bug。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。FindBugs不是通过分析类文件的形式或结构来确定程序的意图,而是利用字节码分析和很多内置的 bug 模式检测器来查找代码中的常见bug。它可以帮助您找出代码的哪些位置有意或者无意地偏离了良好的设计原理。

二、FindBugs能检查出哪些问题

下面列出了FindBugs可以检查出的一些常见的问题:

1、找出 hash equals 不匹配

这个检测器寻找与 equals() 和 hashCode() 的实现相关的几个问题。这两个方法非常重要,因为几乎所有基于集合的类—— List、Map、Set 等都调用它们。

2、忽略方法返回值

这个检测器查找代码中忽略了不应该忽略的方法返回值的地方。这种情况的一个常见例子是在调用 String 方法时,如在清单 1 中:

清单 1. 忽略返回值的例子

1 String aString = "bob";

2 b.replace('b', 'p');

3 if(b.equals("pop"))

这个错误很常见。在第 2 行,程序员认为他已经用 p 替换了字符串中的所有 b。确实是这样,但是他忘记了字符串是不可变的。所有这类方法都返回一个新字符串,而从来不会改变消息的接收者。

3、Null 指针对 null 的解引用(dereference)和冗余比较

这个检测器查找两类问题。它查找代码路径将会或者可能造成 null 指针异常的情况,它还查找对 null 的冗余比较的情况。例如,如果两个比较值都为 null,那么它们就是冗余的并可能表明代码错误。FindBugs 在可以确定一个值为 null 而另一个值不为 null 时,检测类似的错误,如清单 2 所示:

清单 2. Null 指针示例

1 Person person = aMap.get("bob");

2 if (person != null) {

3 person.updateAccessTime();

4 }

5 String name = person.getName();

在这个例子中,如果第 1 行的 Map 不包括一个名为“bob”的人,那么在第 5 行询问 person 的名字时就会出现 null 指针异常。因为 FindBugs 不知道 map 是否包含“bob”,所以它将第 5 行标记为可能 null 指针异常。

4、初始化之前读取字段

这个检测器寻找在构造函数中初始化之前被读取的字段。这个错误通常是——尽管不总是如此——由使用字段名而不是构造函数参数引起的,如清单 3 所示:

清单 3. 在构造函数中读取未初始化的字段

1 public class Thing {

2 private List actions;

3 public Thing(String startingActions) {

4 StringTokenizer tokenizer = new StringTokenizer(startingActions);

5 while (tokenizer.hasMoreTokens()) {

6 actions.add(tokenizer.nextToken());

7 }

8 }

9 }

在这个例子中,第 6 行将产生一个 null 指针异常,因为变量 actions 还没有初始化。

5、打开IO输入输出流没有关闭的问题。

如下例所示:

try {

boolean readerFlag = true;

BufferedReader reader = new BufferedReader(new FileReader("d://test.txt"));

while (readerFlag) {

allWordInTxt = reader.readLine();

diTxt = reader.readLine();

String end = reader.readLine();

if (end == null) {

readerFlag = false;

break;

}

}

} catch (FileNotFoundException e1) {

e1.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

其它常见问题:

· 无限循环。

· 开启数据库连接没有关闭的问题(只能检查java.sql.Connection,封装后的情况检查不出来)。

· 在不同类型的变量中使用equals()判断是否相等。

· 硬编码问题。

· 定义从来不会被使用的变量。

· 一直不会被执行到的代码块。

· 需要做空指针检查而没有检查的地方。

· 重复赋值问题。

· 没有异常抛出的地方做了异常检查。

· 无意义的toString()方法使用,比如在数组上调用toString()。

· 在循环中大量使用“+”进行字符串连接。

· 对返回boolean值的方法调用没有做返回结果检查。

· 重复的判断条件。

FindBugs 网站提供了完整的 缺陷清单及说明:http://findbugs.sourceforge.net/bugDescriptions.html

三、Findbugs的安装使用

· 下载findbugs插件,解压后复制到eclipse/plugins目录下,重启eclipse。

· 安装成功后在Windows->Preferences->Java->Findbugs可以设置findbugs的常用属性。包括错误分析级别,设置必须检查的错误类别等。

clip_image002

· 打开一个java工程,在package视图下,在需要检查的包上点鼠标右键,执行Find Bugs -> Find Bugs,开始检查可能导致bug的代码。

clip_image004

检查完毕后,打开FindBugs视图,在Bug Explorer视图中可以查看检查到错误,双击定位到错误代码。点击代码左边的臭虫图标,可以查看错误的详细描述。

clip_image006

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics