FindBugs错误分析说明 - 图文 联系客服

发布时间 : 星期一 文章FindBugs错误分析说明 - 图文更新完毕开始阅读5844b36ca6c30c2259019ec1

Bug: Doomed test for equality to NaN

Pattern id: FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER, type: FE, category: CORRECTNESS 解释:

我也开眼界了,照搬Findbugs的理解:

大概意思就是说Nan很特殊(表示未定义和不可表示的值),没有任何值跟它相等,包括它 自身,所以x == Double.NaN永远返回false。 解决方法:

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

26. FI_EMPTY

Bug: FilterIPConfigDialog.finalize() is empty and should be deleted Pattern id: FI_EMPTY, type: FI, category: BAD_PRACTICE 解释:

空的finalize方法,有什么用?

根据JDK文档, finalize() 是一个用于释放非 Java 资源的方法。但是, JVM 有很大的可能不 调用对象的finalize() 方法,因此很难证明使用该方法释放资源是有效的。 解决方法:

删除掉finalize方法

27.REC_CATCH_EXCEPTION

Bug: Exception is caught when Exception is not thrown

Pattern id: REC_CATCH_EXCEPTION, type: REC, category: STYLE 解释:

我觉得有点迷惑,有些catch (Exception e)并没有被Findbugs捕捉到,开始以为它的意思是 try catch里没有任何异常的产生,包括RuntimeException,但是后来我写了例子证明并不是 这么回事。

总之,它的意思应该是说JVM对RuntimeException有统一的捕获机制(一般都是打印异常 栈信息,然后向外抛,没有遇到Exception线程就死掉,EDT线程除外),你搞一个catch (Exception e)这样也把RuntimeException就捕获了。但是如果你的处理机制中没有针对这些 异常,那就可能有问题了。通常来说,很多应用程序都把异常记录在日志之中,但是我觉得 也应该同时打印在调试屏幕中,这样有利于开发人员调试。

比如上面的程序,假如发生了空指针异常,你只有去日志中才能看到,这对我们调试人员来 说很不方便的。 解决方法:

其实这样写也没有问题(除非你有意),有时候我们确实需要捕获RuntimeException,比如 我们有一个批处理,这个任务很重要,必须保证某个任务出了问题不能影响其他的任务,这 个时候就可以在for循环内捕获RuntimeException,出现了异常还可以continue。 不过上面的例子最好再把异常信息打印到调试屏幕上。

28. DM_GC

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 GC和Full GC,Scavenge GC一般是针对年轻代区(Eden区)进行 GC,不会影响老年代和永生代(PerGen),由于大部分对象都是从Eden区开始的,所以 Scavenge GC会频繁进行,GC算法速度也更快,效率更高。但是Full GC不同,Full GC是对 整个堆进行整理,包括Young、Tenured和Perm,所以比Scavenge GC要慢,因此应该尽可 能减少Full GC的次数。 解决方法:

去掉System.gc()

28. DP_DO_INSIDE_DO_PRIVILEGED

Bug: com.taobao.sellerservice.core.test.BaseTestJunit.autoSetBean() invokes reflect.Field.setAccessible(boolean), which should be invoked from within a doPrivileged block

Pattern id: DP_DO_INSIDE_DO_PRIVILEGED, type: DP, category: BAD_PRACTICE

This code invokes a method that requires a security permission check. If this code will be granted security permissions, but might be invoked by code that does not have security permissions, then the invocation needs to occur inside a doPrivileged block.

此代码调用一个方法,需要一个安全权限检查。如果此代码将被授予安全权限,但可能是由 代码不具有安全权限调用,则需要调用发生在一个doPrivileged的块。

30. MS_SHOULD_BE_FINAL

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

使用public和protected,别的包可以轻易修改它,如果你不想它被修改,请使用final。 封装很重要,不管是从维护方面和技术方面来说,都很重要,我不明白为神马有那么多的人 把变量都写成public的(就算要给别人共享,也要提供get方法),特别是在并发环境中, 特别特别注意类变量的共享,而且特别特别特别注意共享的这个变量是否是线程安全的。 解决方法: 加上final

31. NM_FIELD_NAMING_CONVENTION

Bug: The field name TopoControlPaneII.SyncSelection doesn't start with a lower case letter Pattern id: NM_FIELD_NAMING_CONVENTION, type: Nm, category: BAD_PRACTICE 解释:

为神马字段是大写开头的?喂神马?喂神马啊? 解决方法:

建议按照sun规定的命名方式