前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FindBugs的使用

FindBugs的使用

作者头像
一头小山猪
发布2020-04-10 15:18:12
1.4K0
发布2020-04-10 15:18:12
举报
文章被收录于专栏:微光点亮星辰微光点亮星辰

FindBugs的使用

1 FindBugs简介

FindBugs是一个静态分析工具,它检查类或者JAR文件,将字节码与一组缺陷模式进行对比以发现可能的问题。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。FindBugs有几种,有的为单机程序版,有的为与Eclipse相结合的插件版,等等。本文介绍的就是Java程序员最喜欢的插件版。

2 FindBugs的安装

在网上下载FindBugs插件,解压后,直接将解压后的文件(edu.umd.cs.findbugs.plugin.eclipse_3.0.1.20150306-5afe4d1)放到eclipse的dropins目录,然后重启eclipse即可。右键点击项目,看到Find Bugs出现就可以了。

3 FindBugs在Eclipse的使用

在需要静态检查的项目上点击右键,按照上图所示,点击Find Bugs,等待静态检查进度完成。

小瓢虫所在位置即为问题代码所在位置。

检测出的bugs可以到《详解FindBugs的各项检测器》中查找对应原因。

4 FindBugs可以检测的内容

FindBugs提供了35个检测器来检测字节码中可能的缺陷。其可以做的事情主要有:

4.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()方法。

4.2检测:忽略方法返回值

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

1 String aString ="bob";

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

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

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

4.3检测: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指针异常。

4.4检测:初始化之前读取字段

这个检测器寻找在构造函数中初始化之前被读取的字段。这个错误通常是由使用字段名而不是构造函数参数引起的,例如在构造函数中读取未初始化的字段:

1 public class Thing {

2 private List actions;

3 public Thing(StringstartingActions) {

4 StringTokenizertokenizer =

5 newStringTokenizer(startingActions);

6 while(tokenizer.hasMoreTokens()) {

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

8 }

9 }

10 }

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

4.5命名检查

对标准Java命令规范的测试:变量名称不应太短;方法名称不应过长;类名称应当以小写字母开头;方法和字段名应当以小写字母开头,等等。

4.6未使用的代码检查

查找从未使用的私有字段和本地变量、执行不到的语句、从未调用的私有方法,等等。

4.7嵌套检查

例如:switch语句应当有default块,应当避免深度嵌套的if块,不应当给参数重新赋值,不应该对double值进行相等比较。

4.8导入语句检查

检查import语句的问题,比如同一个类被导入两次或者被导入java.lang的类中。

4.9JUnit测试检查

查找测试用例和测试方法的特定问题,例如方法名称的正确拼写,以及suite()方法是不是static和public。

4.10字符串检查

找出处理字符串时遇到的常见问题,例如重复的字符串标量,调用String构造函数,对String变量调用toString()方法。

4.11括号检查

检查for、if、while和else语句是否使用了括号。

4.12代码尺寸检查

测试过长的方法、有太多方法的类以及重构方面的类似问题。

4.13终结函数检查

因为在Java语言中,finalize()方法不是那么普遍,它们的使用规则虽然很详细,但是人们对它们相对不是很熟悉。这类检查查找finalize()方法的各种问题,例如空的终结函数,调用其他方法的finalize()方法,对finalize()的显式调用,等等。

4.14克隆检查

用于clone()方法的新规则。凡是重写clone()方法的类都必须实现Cloneable,clone()方法应该调用super.clone(),而clone()方法应该声明抛出CloneNotSupportedException异常,即使实际上没有抛出异常,也要如此。

4.15耦合检查

查找类之间过度耦合的迹象,比如导入内容太多;在超类型或接口就已经够用的时候使用子类的类型;类中的字段、变量和返回类型过多等。

4.16异常检查

针对异常的检查:不应该声明该方法而抛出java.lang.Exception异常,不应当将异常用于流控制,不应该捕获Throwable,等等。

4.17日志检查

查找java.util.logging.Logger的不当使用,包括非终状态(nonfinal)、非静态的记录器,以及在一个类中有多个记录器。

4.18Open—Close检查

检查文件或通讯方面,是否忘记Close的情况。

4.19其它检查

其它缺陷清单可参见:缺陷清单

4.20构建自己的规则集

可以构建自己的规则集。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-01-03,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 微光点亮星辰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 FindBugs简介
  • 2 FindBugs的安装
  • 3 FindBugs在Eclipse的使用
  • 4 FindBugs可以检测的内容
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com