Java 代码缺陷自动分析工具介绍
Java 代码缺陷自动分析工具介绍
Java 代码缺陷自动分析工具主要有:Findbugs、PMD 和 CheckStyle 工具。这里重点介 绍 Findbugs 的使用,简要提及 PMD 和 CheckStyle 工具的使用。
是什么? 1 FindBugs 是什么?
FindBugs 是一个 java bytecode 静态分析工具, 它可以帮助 java 工程师提高代码质量 以及排除隐含的缺陷。 FindBugs 检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问 题。 有了静态分析工具,就可以在不实际运行程序的情况对
软件进行分析。FindBugs 不是 通过分析类文件的形式或结构来确定程序的意图,而是通常使用 Visitor 模式进行分析 。 (Visitor 模式的更多信息)
2
可以做什么? FindBugs 可以做什么?
FindBugs 提供了 35 个检测器来检测字节码中可能的缺陷。可以做的事情主要有: 2.1 找出 hash equals 不匹配
找与 equals() 和 hashCode() 的实现相关的几个问题。 这两个方法非常重要, 因 为几乎所有基于集合的类---List、Map、Set 等都调用它们。一般来说,这个检测器寻 找两种不同类型的问题: ①当一个类重写对象的 equals() 方法, 但是没有重写它的 hashCode 方法, 或者 相反的情况时。 ②定义一个 co-variant 版本的 equals() 或 compareTo() 方法。 例如, Bob 类 定义其 equals() 方法为布尔 equals(Bob) , 它覆盖了对象中定义的 equals() 方法。 因为 Java 代码在编译时解析重载方法的方式, 在运行时使用的几乎总是在对象中定义 的这个版本的方法,而不是在 Bob 中定义的那一个(除非显式将 equals() 方法的参 数强制转换为 Bob 类型)因此, 。 当这个类的一个实例放入到类集合中的任何一个中时, 使用的是 Object.equals() 版本的方法, 而不是在 Bob 中定义的版本。 在这种情况下, Bob 类应当定义一个接受类型为 Object 的参数的 equals() 方法。
2.2
检测: 检测:忽略方法返回值 这个检测器查找代码中忽略了不应该忽略的方法返回值的地方。 这种情况的一个常
常用工具培训资料 黄锡波 2005-08-18
Page 1 of 14
Java 代码缺陷自动分析工具介绍 见例子是在调用 String 方法时,例如: 1 String aString = "bob"; 2 b.replace('b', 'p'); 3 if(b.equals("pop")) 这个错误很常见。在第 2 行,程序员认为他已经用 p 替换了字符串中的所有 b。 确实是这样,但是他忘记了字符串是不可变的。所有这类方法都返回一个新字符串,而 从来不会改变消息的接收者。
2.3
检测: 的解引用(dereference) 检测:Null 指针对 null 的解引用(dereference)和冗余比较
这个检测器查找两类问题。 它查找代码路径将会或者可能造成 null 指针异常的情 况,它还查找对 null 的冗余比较的情况
。例如,如果两个比较值都为 null,那么它 们就是冗余的并可能表明代码错误。FindBugs 在可以确定一个值为 null 而另一个值 不为 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 指针异常。
2.4
检测: 检测:初始化之前读取字段
这个检测器寻找在构造函数中初始化之前被读取的字段。 这个错误通常是由使用字 段名而不是构造函数参数引起的,例如在构造函数中读取未初始化的字段: 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 指针异常, 第 因