FindBugs What Why How



什么是静态代码分析

静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,找出代码隐藏的错误和缺陷,如参数不匹配,有歧义的嵌套语句,错误的递归,非法计算,可能出现的空指针引用等等。

在软件开发过程中,静态代码分析往往先于动态测试之前进行,同时也可以作为制定动态测试用例的参考。统计证明,在整个软件开发生命周期中,30% 至 70% 的代码逻辑设计和编码缺陷是可以通过静态代码分析来发现和修复的。


静态代码分析工具的优势

1. 帮助程序开发人员自动执行静态代码分析,快速定位代码隐藏错误和缺陷。

2. 帮助代码设计人员更专注于分析和解决代码设计缺陷。

3. 显著减少在代码逐行检查上花费的时间,提高软件可靠性并节省软件开发和测试成本。


静态代码分析工具的分类

PMD CheckStyle 是基于.java 文件,会生成抽象语法树 AST,检测的规则基于语法块和表达式 。侧重点是编码风格,未使用的代码,重复代码等等层面的检测

FindBugs 是基于class文件或者jar包。在字节码层面,通过内置的一套规则进行缺陷模型的匹配,由于模型并不一定完全匹配,会有误报漏报的产生, 另外由于是在字节码层面,单纯的从代码角度看,有的错误会让人觉得困惑。

FindBugs 和 Sonar

findbugs是sonar的子集,在sonar平台中可以直接导入findbugs的规则集。sonar比findbugs高了一个层级,多出了sonar不仅关注了常规静态bug,还关注到了如代码质量、包与包,类与类之间的依赖情况、代码耦合情况、类,方法。文件的复杂度、代码中是否包含大量复制粘贴的代码是质量低下的,关注到了项目代码整体的健康情况。不过个人在使用过程中findbugs本身的规则比sonar的官方规则更加实用,high级别的bug都是较为实用的bug,且能覆盖到一些性能方面的问题,sonar的规则,50%bug都是主要级别,其实危害不大。


安装和使用

Findbugs的缺陷

 

 Call to equals() comparing different types

equals接受的参数是object,传入其他类型并不会报错。所以需要确认到底本意如此还是代码中的bug


equals的实现

修改方法:

下面和上面的错误是类似的,但是有一点好,常量前置,避免了变量为null,引起空指针错误

 No relationship between generic parameter and method argument

调用contains的时候, 泛型参数和传入的方法参数不匹配

This call to a generic collection method contains an argument with an incompatible class from that of the collection's parameter (i.e., the type of the argument is neither a supertype nor a subtype of the corresponding generic type argument). Therefore, it is unlikely that the collection contains any objects that are equal to the method argument used here. Most likely, the wrong value is being passed to the method.
In general, instances of two unrelated classes are not equal. For example, if the Foo and Bar classes are not related by subtyping, then an instance of Foo should not be equal to an instance of Bar. Among other issues, doing so will likely result in an equals method that is not symmetrical. For example, if you define the Foo class so that a Foo can be equal to a String, your equals method isn't symmetrical since a String can only be equal to a String.

一般来讲,两个不同的class是不会相等的,除非你自己实现了特定的equals方法,但是String只能和String相等

contains方法在arrayList中的实现



Suspicious reference comparison

两个对象直接用==比较,比较的是堆空间上的内存地址

另外:自动拆箱只存在与一个是对象,一个是基本类型


Impossible cast

不可能成功的转型

This cast will always throw a ClassCastException. FindBugs tracks type information from instanceof checks, and also uses more precise information about the types of values returned from methods and loaded from fields. Thus, it may have more precise information that just the declared type of a variable, and can use this to determine that a cast will always throw an exception at runtime.



equals method overrides equals in superclass and may not be symmetric

 重写父类的equals方法,可能导致a 等于b,但是b不等于a的现象出现

This class defines an equals method that overrides an equals method in a superclass. Both equals methods methods use instanceof in the determination of whether two objects are equal. This is fraught with peril, since it is important that the equals method is symmetrical (in other words, a.equals(b) == b.equals(a)). If B is a subtype of A, and A's equals method checks that the argument is an instanceof A, and B's equals method checks that the argument is an instanceof B, it is quite likely that the equivalence relation defined by these methods is not symmetric.


 



Null value is guaranteed to be dereferenced:

需要进行非空的判断,(只要对于对象是否是空进行了判断就默认处理了null的情况)

修改方法

Method call passes null for non-null parameter

对于不接受null值的方法,传入的参数要进行空判断。

分析:

修改方法:


Possible null pointer dereference

有可能是误报


An apparent infinite recursive loop

企图调用不定参数引发的循环调用



测试样例

More arguments are passed than are actually used in the format string

字符串格式化中的占位符数量与期望值不符

修改方法,使用Java提供的格式化方式

性能问题:

Boxing/unboxing to parse a primitive

setCardID接受一个基本类型 , this.cardKey是String类型


valueOf的实现 


修改方式,能传基本类型,就用parseXXX这样方法


Method concatenates strings using + in a loop

在循环中用+拼接字符串

Why :


java,或者更具体的说,编译器 针对+做了操作符重载,对于字符串拼接的+,会生成StringBuilder

如果是循环,就会循环创建StringBuilder对象


总结

Findbugs 分析代码的能力是有限的,它主要目的作用是定位问题,之后更多的是需要人为的介入分析代码。工具的最终的目的是为了增强代码的健壮性,所以也不要一味追求解决所有的扫描结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值