找出代码中已有的缺陷,提高代码质量,排除潜在隐患是每个程序员的责任,不管是入门者还是资深者都被这个问题困扰着。
实际开发中会有特别多的伪问题存在,伪问题就是一些不是问题的问题,也可理解成误报。 本来不是问题的地方被当作成问题,无疑会耽误大量时间去发现和排除。由此可见所以静态代码分析尤为重要。
这里推荐一款我正在使用的工具: Findbugs
Find bugs - This is the web page for FindBugs, a program which uses static analysis to look for bugs in Java code.
http://findbugs.sourceforge.net/
它的特点是不重视格式和样式。
网上有些资料可供参考:
这个检测器寻找与 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()方法。
这个检测器查找代码中忽略了不应该忽略的方法返回值的地方。这种情况的一个常见例子是在调用 String 方法时,如在清单 1 中:
1 String aString = "bob";
2 b.replace('b', 'p');
3 if(b.equals("pop"))
|
这个检测器查找两类问题。它查找代码路径将会或者可能造成 null 指针异常的情况,它还查找对 null 的冗余比较的情况。例如,如果两个比较值都为 null ,那么它们就是冗余的并可能表明代码错误。 FindBugs 在可以确定一个值为 null 而另一个值不为 null 时,检测类似的错误,如清单 2 所示:
1 Person person = aMap.get("bob");
2 if (person != null) {
3 person.updateAccessTime();
4 }
5 String name = person.getName();
|
这个检测器寻找在构造函数中初始化之前被读取的字段。这个错误通常是 —— 尽管不总是如此 —— 由使用字段名而不是构造函数参数引起的,如清单 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 }
|