zoukankan      html  css  js  c++  java
  • findBugs学习小结

    今天代码质量再次强调java代码提交SVN前要经过findBugs检查,虽然根据菜单我也基本会有findBugs插件,但为了更全面的学习、更高效的利用,我搜索学习了findbugs的用法。

    检查原理

    Findbugs是一个静态分析工具,它检查类或者JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。Findbugs自带检测器,其中有60余种Bad practice,80余种Correctness,1种 Internationalization,12种Malicious code vulnerability,27种Multithreaded correctness,23种Performance,43种Dodgy。我们还可以自己配置检查规则(做哪些检查,不做哪些检查),也可以自己来实现独有的校验规则(用户自定义特定的bug模式需要继承它的接口,编写自己的校验类,属于高级技巧)。

     白盒测试中的静态检查一般是检查编码标准规范,错误列表。编码规范往往团队会根据自己的经验和风格进行设置一些规范。现在很多IDE工具都会在编辑代码的时候实时的提醒是否符合代码风格。错误列表,一般是代码潜在的bug,由于某种代码写法虽然没有语法错误,但是可能存在错误,比如会导致线程死锁。这些都是错误列表应该检查的。静态检查的可操作方式:

     1、代码走查:

      程序员之间可以隔一定的时间抽取代码进行走查。

      走查的时候根据汇总报告,把这些经验汇成列表,作为下次代码走查的依据。

      该方式的特点是,手工、多人讨论、操作简单,但是效率会比较低。

     2、代码扫描

    使用软件对我们的代码进行扫描,查找出潜在的问题。现在有许多商业的工具能够进行扫描,比如Parasoft JTest、Software Analyzer、pclint等工具,往往不同的工具会针对不同的语言。当然也有很多开源的工具。在这里java方面主要推荐Findbugs。Findbugs可以在ANT/GUI/ECLIPSE三个环境中运行,同时也可以编写自己的检测器,功能比较完善。我们平时可以收集自己的或者是别人的开发经验,把它做成检测器来完善Findbugs的检测体系。软件扫描的特点是,机器扫描、效率高,但是没不够灵活,扩展比较负责。

    Java静态检查工具对比

    参考:http://blog.csdn.net/ml5271169588/article/details/6975701

    http://www.cnblogs.com/hyddd/archive/2008/12/16/1356310.html

    工具

    目的

    检查项

    FindBugs

    检查.class

    基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug

    主要检查bytecode中的bug patterns,如NullPoint空指针检查、没有合理关闭资源、字符串相同判断错(==,而不是equals)等

    PMD

    检查源文件

    检查Java源文件中的潜在问题

    主要包括:

    空try/catch/finally/switch语句块

    未使用的局部变量、参数和private方法

    空if/while语句

    过于复杂的表达式,如不必要的if语句等

    复杂类

    CheckStyle

    检查源文件

    主要关注格式

    检查Java源文件是否与代码规范相符

    主要包括:

    Javadoc注释

    命名规范

    多余没用的Imports

    Size度量,如过长的方法

    缺少必要的空格Whitespace

    重复代码

    使用及配置

    摘自:http://developer.51cto.com/art/200906/127165.htm

    本文主要介绍在Eclipse中使用的情况

    FindBugs是一个可以在Java程序中发现Bugs的程序。它是专门用来寻找处于"Bug Patterns"列表中的代码的。Bug Patterns指很有可能是错误的代码的实例。

    打开Bug Details视图Windows => Show View => Other… => FindBugs => BugDetails

    在Package Explorer或Navigator视图中,选中你的Java项目,右键,可以看到"Find Bugs"菜单项,子菜单项里有"Find Bugs"和"Clear Bug Markers"两项内容,如下图所示:

    我们建立一个简单的测试文件Test.java 内容如下:

    public class Test

    {

    private String[] name;

    public String[] getName()

    {

    return name;

    }

    public void setName(String[] name)

    {

    this.name = name;

    }

    }

    我们点中"Find Bugs",运行时会出现如下进度框:

    运行结束后可以在Problems中看到增加了如下的警告信息内容

    FindBugs运行后的警告信息内容不仅在Problems视图中显示,而且将标记在源代码标记框中,在源代码编辑器中我们可以看到警告标识,如下图:

    当光标指向你的警告信息的代码上面时,就会有相应的错误提示信息,与Eclipse本身的错误或警告信息提示类似。

    选中Problems视图里出现的相应问题,就会在代码编辑器里切换到相应的代码上去,方便根据相应的提示信息进行代码的修改。

    在Problems视图里,选中相应的问题条目,右键,在弹出的菜单中,可以看到"Show Bug Details",如下图所示:

    点中它,会切换到Bug Details视图上去,显示更加详细的提示信息。

    当然,在代码编辑窗口中,点击带有警告提示信息的图标时,也会自动切换到Bud Details窗口去,查看详细的警告信息,如下图所示。

    根据这里详细的信息,你可以得到FindBugs为什么会对你的代码报警告信息,及相应的处理办法,根据它的提示,你可以快速方便地进行代码修改。

    根据提示,我们将代码修改成如下,再运行就不会报有警告信息了。

    public class Test

    {

    private String[] name;

    public String[] getName()

    {

    String[] temp = name;

    return temp;

    }

    public void setName(String[] name)

    {

    String[] temp = name;

    this.name = temp;

    }

    }

    配置FindBugs

    选择你的项目,右键 => Properties => FindBugs =>

    可以配置的信息包括如上图所示的四个选项的相关设置:

    1. Run FindBugs Automatically开关

    当此项选中后,FindBugs将会在你修改Java类时自动运行,如你设置了Eclipse自动编译开关后,当你修改完Java文件保存,FindBugs就会运行,并将相应的信息显示出来。

    当此项没有选中,你只能每次在需要的时候自己去运行FindBugs来检查你的代码。

    2. Minimum priority to report选择项

    这个选择项是让你选择哪个级别的信息进行显示,有Low、Medium、High三个选择项可以选择,很类似于Log4J的级别设置啦。 比如:

    你选择了High选择项,那么只有是High级别的提示信息才会被显示。

    你选择了Medium选择项,那么只有是Medium和High级别的提示信息才会被显示。

    你选择了Low选择项,那么所有级别的提示信息都会被显示。

    3. Enable bug categories选择项

    在这里是一些显示Bug分类的选择:

    Correctness关于代码正确性相关方面的

    Performance关于代码性能相关方面的

    Internationalization关于代码国际化相关方面的

    Multithreaded correctness关于代码多线程正确性相关方面的

    Style关于代码样式相关方面的

    Malicious code vulnerability关于恶意破坏代码相关方面的

    比如:如果你把Style的检查框去掉不选择中它,那么与Style分类相关的警告信息就不会显示了。其它的类似。

    4. Select bug patterns to check for选择项

    在这里你可以选择所要进行检查的相关的Bug Pattern条目

    可以从Bug codes、Detector name、Detector description中看到相应的是要检查哪些方面的内容,你可以根据需要选择或去掉相应的 检查条件。

    三、详细说明

    Findbugs是一个静态分析工具,它检查类或者JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。Findbugs自带检测器,其中有60余种Bad practice,80余种Correctness,1种 Internationalization,12种Malicious code vulnerability,27种Multithreaded correctness,23种Performance,43种Dodgy。

    Bad practice 坏的实践

    一些不好的实践,下面列举几个:

    HE: 类定义了equals(),却没有hashCode();或类定义了equals(),却使用

    Object.hashCode();或类定义了hashCode(),却没有equals();或类定义了hashCode(),却使用Object.equals();类继承了equals(),却使用Object.hashCode()。

    SQL:Statement 的execute方法调用了非常量的字符串;或Prepared Statement是由一个非常量的字符串产生。

    DE: 方法终止或不处理异常,一般情况下,异常应该被处理或报告,或被方法抛出。

    Correctness 一般的正确性问题

    可能导致错误的代码,下面列举几个:

    NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否null;null值产生并被引用;null值产生并在方法的异常路径被引用;传给方法一个声明为@NonNull的null参数;方法的返回值声明为@NonNull实际是null。

    Nm: 类定义了hashcode()方法,但实际上并未覆盖父类Object的hashCode();类定义了tostring()方法,但实际上并未覆盖父类Object的toString();很明显的方法和构造器混淆;方法名容易混淆。

    SQL:方法尝试访问一个Prepared Statement的0索引;方法尝试访问一个ResultSet的0索引。

    UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。

    Internationalization 国际化

    当对字符串使用upper或lowercase方法,如果是国际的字符串,可能会不恰当的转换。

    Malicious code vulnerability 可能受到的恶意攻击

    如果代码公开,可能受到恶意攻击的代码,下面列举几个:

    FI: 一个类的finalize()应该是protected,而不是public的。

    MS:属性是可变的数组;属性是可变的Hashtable;属性应该是package protected的。

    Multithreaded correctness 多线程的正确性

    多线程编程时,可能导致错误的代码,下面列举几个:

    ESync:空的同步块,很难被正确使用。

    MWN:错误使用notify(),可能导致IllegalMonitorStateException异常;或错误的

    使用wait()。

    No: 使用notify()而不是notifyAll(),只是唤醒一个线程而不是所有等待的线程。

    SC: 构造器调用了Thread.start(),当该类被继承可能会导致错误。

    Performance 性能问题

    可能导致性能不佳的代码,下面列举几个:

    DM:方法调用了低效的Boolean的构造器,而应该用Boolean.valueOf(…);用类似

    Integer.toString(1) 代替new Integer(1).toString();方法调用了低效的float的构造器,应该用静态的valueOf方法。

    SIC:如果一个内部类想在更广泛的地方被引用,它应该声明为static。

    SS: 如果一个实例属性不被读取,考虑声明为static。

    UrF:如果一个属性从没有被read,考虑从类中去掉。

    UuF:如果一个属性从没有被使用,考虑从类中去掉。

    Dodgy 危险的

    具有潜在危险的代码,可能运行期产生错误,下面列举几个:

    CI: 类声明为final但声明了protected的属性。

    DLS:对一个本地变量赋值,但却没有读取该本地变量;本地变量赋值成null,却没有读取该本地变量。

    ICAST: 整型数字相乘结果转化为长整型数字,应该将整型先转化为长整型数字再相乘。

    INT:没必要的整型数字比较,如X <= Integer.MAX_VALUE。

    NP: 对readline()的直接引用,而没有判断是否null;对方法调用的直接引用,而方法可能返回null。

    REC:直接捕获Exception,而实际上可能是RuntimeException。

    ST: 从实例方法里直接修改类变量,即static属性。

    可参考:http://blog.csdn.net/fanyuna/article/details/6860198

  • 相关阅读:
    mySQL练习题
    JAVA实现C/S结构小程序
    JavaLinkedHashSet练习
    关于Extjs删除分页后删除最后一条数据页面无效的问题。
    hibernate 插入,更新数据库错误
    错误!错误!错误!
    坑爹的oracle
    关于hibernate实体类
    第一个项目的需求分析
    Ueditor 单独使用上传图片及上传附件方法
  • 原文地址:https://www.cnblogs.com/jpfss/p/9019303.html
Copyright © 2011-2022 走看看