关于静态代码分析

    技术2022-05-19  23

      关于静态代码分析 

      找出代码中已有的缺陷,提高代码质量,排除潜在隐患是每个程序员的责任,不管是入门者还是资深者都被这个问题困扰着。

    实际开发中会有特别多的伪问题存在,伪问题就是一些不是问题的问题,也可理解成误报。 本来不是问题的地方被当作成问题,无疑会耽误大量时间去发现和排除。由此可见所以静态代码分析尤为重要。

      这里推荐一款我正在使用的工具: 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/

      它的特点是不重视格式和样式。

    网上有些资料可供参考:

     

    下面的列表没有包括  FindBug  可以找到的 所有 问题。相反,我侧重于一些更有意思的问题。 检测器:找出  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() 方法。 检测器:忽略方法返回值   这个检测器查找代码中忽略了不应该忽略的方法返回值的地方。这种情况的一个常见例子是在调用 String 方法时,如在清单  1  中:  1.  忽略返回值的例子 1  String aString = "bob"; 2  b.replace('b', 'p'); 3  if(b.equals("pop"))   这个错误很常见。在第  2  行,程序员认为他已经用  p  替换了字符串中的所有  b 。确实是这样,但是他忘记了字符串是不可变的。所有这类方法都返回一个新字符串,而从来不会改变消息的接收者。 检测器: 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  指针异常。 检测器:初始化之前读取字段   这个检测器寻找在构造函数中初始化之前被读取的字段。这个错误通常是 —— 尽管不总是如此 —— 由使用字段名而不是构造函数参数引起的,如清单  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 还没有初始化。 FindBugs 暂时 提供总共  35  个检测器。

    最新回复(0)