FindBugs是一种java代码的静态分析工具,无需开发人员费劲就能找出代码中可能存在的缺陷。FindBugs 不注重样式或者格式,它试图只寻找缺陷或者潜在的性能问题。

第一步,http://sourceforge.net/projects/findbugs/files/findbugs%20eclipse%20plugin/下载zip包,解压到eclipse的plugins目录,重新启动eclipse。

第二步,工程右键中应该出现了FindBugs,点击应用。

Bug: Call to equals() comparing different types
Pattern id: EC_UNRELATED_TYPES, type: EC, category:
CORRECTNESS

解释:

两个不同类型的对象调用equals方法,如果equals方法没有被重写,那么调用object的==,永远不会相等。

解决方法

应该改为str.toString()

Bug: Check
for oddness that won't work for negative numbers
Pattern id: IM_BAD_CHECK_FOR_ODD, type: IM, category:
STYLE

解释:

如果row是负奇数,那么row % 2 == -1,

解决方法:

考虑使用x & 1 == 1或者x % 2 != 0

Bug:
PerfmSingleGraphPanel$RSCategory defines equals and uses Object.hashCode()
Pattern id: HE_EQUALS_USE_HASHCODE, type: HE, category:
BAD_PRACTICE

解释:

重载了equals方法,却没有重载hashCode方法,如果使用object自己的hashCode,我们可以从JDK源代码可以看到object的hashCode方法是native的,它的值由虚拟机分配(某种情况下代表了在虚拟机中的地址或者唯一标识),每个对象都不一样。

  equals用于判定两个对象是否为同一对象,程序员得根据自己的需要重写这个方法来达到对象比较的目的。
hashcode是用来提高效率的,HashSet和HashMap是基于hashcode方法来查找对象的,所以你在使用这些类的时候一定要覆盖hashcode方法。
而非散列的Set和Map,例如TreeSet,TreeMap等,它们只需equals方法就可以唯一确定对象的身份。

解决方法:

为了使你写的类能够高效地应用于HashMap/HashTable,请重写hashcode方法。

Bug: "." used for regular expression
Pattern id: RE_POSSIBLE_UNINTENDED_PATTERN, type: RE, category:
CORRECTNESS

解释:

String的split方法传递的参数是正则表达式,正则表达式本身用到的字符需要转义,如:句点符号“.”,美元符号“$”,乘方符号“^”,大括号“{}”,方括号“[]”,圆括号“()” ,竖线“|”,星号“*”,加号“+”,问号“?”等等,这些需要在前面加上“\\”转义符。

解决方法:

在前面加上“\\”转义符。

Bug:
WindowHandlerManager$MySingleSelectionModel is Serializable; consider declaring
a serialVersionUID
Pattern id: SE_NO_SERIALVERSIONID, type: SnVI, category:
BAD_PRACTICE

解释:

实现了Serializable接口,却没有实现定义serialVersionUID字段,序列化的时候,我们的对象都保存为硬盘上的一个文件,当通过网络传输或者其他类加载方式还原为一个对象时,serialVersionUID字段会保证这个对象的兼容性,考虑两种情况:

  1. 新软件读取老文件,如果新软件有新的数据定义,那么它们必然会丢失。
  2. 老软件读取新文件,只要数据是向下兼容的,就没有任何问题。

序列化会把所有与你要序列化对象相关的引用(包括父类,特别是内部类持有对外部类的引用,这里的例子就符合这种情况)都输出到一个文件中,这也是为什么能够使用序列化能进行深拷贝。这种序列化算法给我们的忠告是,不要把一些你无法确定其基本数据类型的对象引用作为你序列化的字段(比如JFrame),否则序列化后的文件超大,而且会出现意想不到的异常。

解决方法:

定义serialVersionUID字段

Bug:
ToStringComparator implements Comparator but not Serializable
Pattern id: SE_COMPARATOR_SHOULD_BE_SERIALIZABLE, type:
Se, category: BAD_PRACTICE

解释:

ToStringComparator类实现了Comparator接口却没有实现Serializable接口。

Comparator提供了比较的一句,利用Collections.sort可完成排序。

为了能够序列化Treemap和TreeSet,那么它们所添加的类,如果实现了Comparators必须支持Serializable接口。

解决方法:

实现Serializable接口并定义serialVersionUID字段

Bug:
ManageItem defines equals(ManageItem) method and
uses Object.equals(Object)
Pattern id: EQ_SELF_USE_OBJECT, type: Eq, category:
CORRECTNESS

解释:

这是重载,不是覆盖,除非你能保证其他人调用这个方法传入的参数都是ManageItem 的,否则会调用Object的boolean equals(Object)方法,这样的话根本就不会跑到这个方法里来。

解决方法:

如果你想覆盖父类的方法,请在上面加上@Override注解,它会防止这种错误的出现。

Bug: Dead
store to date
Pattern id: DLS_DEAD_LOCAL_STORE, type: DLS, category:
STYLE

解释:

定义了却未使用的变量。

解决方法:

大胆的去掉或者注释掉。

Bug:
Doomed test for equality to NaN
Pattern id: FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER, type: FE, category:
CORRECTNESS

解释:

Nan很特殊(表示未定义和不可表示的值),没有任何值跟它相等,包括它自身,所以x ==
Double.NaN永远返回false。

解决方法:

如果要检查x是特殊的,不是一个数值,请用Double.isNaN(x)方法。

Bug:
DBExportTask2.exportDBRecords(DBExportProperty, String) forces garbage
collection; extremely dubious except in benchmarking code
Pattern id: DM_GC, type: Dm, category:
PERFORMANCE

解释:

有两点:

  1. System.gc()只是建议,不是命令,JVM不能保证立刻执行垃圾回收。
  2. System.gc()被显示调用时,很大可能会触发Full GC

GC有两种类型:Scavenge GCFull GCScavenge GC一般是针对年轻代区(Eden区)进行GC,不会影响老年代和永生代(PerGen),由于大部分对象都是从Eden区开始的,所以Scavenge GC会频繁进行,GC算法速度也更快,效率更高。

但是Full GC不同,Full GC是对整个堆进行整理,包括Young、Tenured和Perm,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。

解决方法:

去掉System.gc()

Bug:
IPv4Document.m_strInitString isn't final but should be
Pattern id: MS_SHOULD_BE_FINAL, type: MS, category:
MALICIOUS_CODE

解释:

使用public和protected,别的包可以轻易修改它,如果你不想它被修改,请使用final。

封装很重要,不管是从维护方面和技术方面来说,都很重要,就算要给别人共享,也要提供get方法,特别是在并发环境中,get方法也应该是同步的。

解决方法:

加上final或者变为private的。

Bug:
ActionPatternManager.m_This should be package protected
Pattern id: MS_PKGPROTECT, type: MS, category:
MALICIOUS_CODE

解释:

Findbugs说,静态字段m_oThis应该是包权限的。

单例模式??这是神马单例模式?字段不是private,还是单例模式吗?

解决方法:

修改protected为private,然后将单例模式实现方式改为恶汉,或者双重校验锁定。

Bug:
Incorrect lazy initialization and update of static field
MonitorRuleManager.m_This
Pattern id: LI_LAZY_INIT_UPDATE_STATIC, type: LI, category:
MT_CORRECTNESS

解释:

这是一个多线程的BUG,多线程的问题之所以很严重,是因为我们很难复现解决它,但它又是的确存在的,它总是在关键时候爆发,让你感到很郁闷。

解决方法:

加上synchronized,改成饿汉模式,或者使用双重校验锁。

public class Singleton {

    private volatile static Singleton singleton;

      private Singleton (){}

      public static Singleton getSingleton() {

      if (singleton == null) {

        synchronized (Singleton.class) {

              if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}

}

Bug:
Method JTAMainFrame.initView(JFrame) makes inefficient use of keySet iterator
instead of entrySet iterator
Pattern id: WMI_WRONG_MAP_ITERATOR, type: WMI, category:
PERFORMANCE

解释:

很多人都这样遍历Map,没错,但是效率很低,先一个一个的把key遍历,然后在根据key去查找value,这不是多此一举么,为什么不遍历entry(桶)然后直接从entry得到value呢?它们的执行效率大概为1.5:1(有人实际测试过)。

解决方法:

  for (Map.Entry<String, JMenu> entry : menuList.entrySet()) {

       mb.add(entry.getValue());

}

Bug:
SingleNePollConfigDialog.collectValues(Hashtable) may expose internal
representation by storing an externally mutable object into
SingleNePollConfigDialog.values
Pattern id: EI_EXPOSE_REP2, type: EI2, category:
MALICIOUS_CODE

解释:

参数values保存在当前线程的执行栈中,而this.values保存在堆上,它们同时指向同一个对象,对参数values的任何操作都会影响到this.values,如果你知道这一点,而且本意就是这样的,那么你可以忽略上面这些话,但是下面这些话你应该好好听听。

这是一段正确的代码,但不是一段可维护性强、可理解性强的代码,参数代表操作的条件,它们应该是只读的,我们不应该对它直接进行操作或者赋值。

解决方法:

如果把上面对参数values的操作都改成this.values。

Bug:
temsLoader.getItemsWithPriority() may expose internal representation by
returning ItemsLoader.m_htItemsWithPriority
Pattern id: EI_EXPOSE_REP, type: EI, category:
MALICIOUS_CODE

解释:

刚开始一看挺纳闷的,这个方法有什么问题吗?某些数据集合不应该直接对外提供public返回方法,提供了get方法,但实际上可以任意修改里面的数据。

解决方法:

如果你确定这些数据集合不应该被外界修改,那么对于基本数据类型,你提供get方法即可,对于引用,get方法里的返回值应该是数据的拷贝。

Bug:
Method call passes null for nonnull parameter of queryScriptData(ObjService)
Pattern id: NP_NULL_PARAM_DEREF, type: NP, category:
CORRECTNESS

解释:

当getAllListFiles方法发生了任何异常(checked和unchecked),allFiles都为null,关键是在queryScriptData方法里,并没有对参数是否为null进行判断,它直接调用了参数对象上面的方法,这肯定会发生空指针异常。

一个优秀的程序员,在过马路时都要向两边看一下,在写一个方法时,首先要考虑的就是对方法参数的有效性判断。

解决方法:

在queryScriptData方法里对参数进行有效性判断。

Bug:
TopoCardManagerAction.processLocalCard(Hashtable) invokes inefficient Boolean
constructor; use Boolean.valueOf(...) instead
Pattern id: DM_BOOLEAN_CTOR, type: Dm, category:
PERFORMANCE

解释:

不必创建一个新的Boolean对象,使用Boolean.valueOf方法可以重用Boolean.FALSE和Boolean.TRUE对象。

我们可以从API中可以看到public Boolean(boolean value)方法的解释:注:一般情况下都不宜使用该构造方法。若不需要新 的实例,则静态工厂 valueOf(boolean) 通常是一个更好的选择。这有可能显著提高空间和时间性能。

解决方法:

使用Boolean.valueOf方法或者直接返回Boolean.FALSE和Boolean.TRUE对象。

FindBugs简单应用的更多相关文章

  1. Java静态代码分析工具——FindBugs插件的安装与使用

    1 什么是FindBugs FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题.有了静态分析工具,就可以在不实际运行程序的情况对软件进行分 ...

  2. FindBugs插件的安装与使用

    转载:http://www.cnblogs.com/kayfans/archive/2012/06/18/2554022.html 1 什么是FindBugs FindBugs 是一个静态分析工具,它 ...

  3. 源代码扫描工具Fortify SCA与FindBugs的简单对比

    前段时间因为工作原因需要对java源代码进行扫描,现结合使用经验对静态代码扫描工具Fortify SCA与FindBugs进行一个简单的对比. 一.Fortify SCA Fortify SCA是由全 ...

  4. MyEclipse2014 设备 checkstyle、PMD、findbugs 最简单的方法 详细说明

    最近的实验需要的代码审查和应用程序性能优化.在需求MyEclipse安装某些插件,由于如今的MyEclipse版本号和大多数教程的不一样了,一些安装选项也已经改变,所以安装起来非常费事,通过不断的尝试 ...

  5. AndroidStudio 插件 之 Findbugs 安装与简单使用教程

    http://blog.csdn.net/u013132758/article/details/70187846 http://blog.csdn.net/jdsjlzx/article/detail ...

  6. FindBugs 入门——帮你减少代码中的bug数

    FindBugs 入门 FindBugs 作用 开发人员在开发了一部分代码后,可以使用FindBugs进行代码缺陷的检查.提高代码的质量,同时也可以减少测试人员给你报的bug数. 代码缺陷分类 根据缺 ...

  7. Eclipse的FindBugs插件

      Eclipse的FindBugs插件     问题提出: 当我们编写完代码,做完单元测试等各种测试后就提交正式运行,只能由运行的系统来检测我们代码是否有问题了,代码中隐藏的错误在系统运行的过程中被 ...

  8. 提高代码质量 CheckStyle FindBugs PMD

    提高代码质量-工具篇 注:这是一篇翻译文章,原文:How to improve quality and syntax of your Android code,为了理解连贯,翻译过程中我修改了一些陈述 ...

  9. Findbugs介绍及使用方法

    1.   简介 Findbugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题.利用这个工具,就可以在不实际运行程序的情况对软件进行分析.它可以帮助改 ...

随机推荐

  1. Socket send函数和recv函数详解

    1.send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP ...

  2. VMware workstation 虚拟机中安装乌班图及其兼容性问题

    之前我在虚拟机中安装乌班图,是先安装好虚拟机,然后将预先下载好的乌班图镜像文件导入安装,这样安装起来还是有些繁琐的,中间要设置好多东西.今天领导给我拷了个虚拟机,还有乌班图的安装文件,是这样的. 对于 ...

  3. vuex的使用

    vue现在越来越火,不单单可以写简单的小项目,也可以写大中型的项目.但是项目大了,项目之间的数据传递就会变得复杂,那么问题来了?在一个大型项目中,多个组件要公用同一个或多个数据,我们如何保证每个组件获 ...

  4. linux 下 用phpmailer类smtp发送邮件始终不成功,提示:ERROR: Failed to co

    https://zhidao.baidu.com/question/509191264.html?fr=iks&word=PHPMailerSMTP+connect()+failed& ...

  5. 数据库复习总结(2)-SQLServer的管理

    1.需要安装SQLServer2008或者SQLServer2012,若要使用SQLServer管理工具进行开发还要安装SQL Server Management Studio,还可以使用Visual ...

  6. ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架。

    ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架.

  7. 【开发技术】 Air display的介绍与使用

    原理是,通过ipad与电脑连接的同一网络,然后把你的ipad变成电脑的屏幕 安装方法:1, 2, 3,

  8. xmind2013激活

    参考链接:http://blog.163.com/m15999573195_1/blog/static/248705063201542622112823/

  9. MySQL Index Merge Optimization

    Index Merge用在通过一些range scans得到检索数据行和合并成一个整体.合并可以通过 unions,intersections,或者unions-intersection运用在底层的扫 ...

  10. MySQL改写子查询成Join

    有时用别的方式而不是子查询可以获得更高的性能 : For example: SELECT * FROM t1 WHERE id IN (SELECT id FROM t2); 改写: SELECT D ...