使用findbugs爲本身的代碼review

轉自:http://blog.lichengwu.cn/java/2013/11/24/use-findbugs-code-review/java

介紹

Findbugs是一個代碼靜態分析工具,用來找出Java代碼中的bug。經過分析字節碼並與一組缺陷模式匹配,找出代碼中的問題。 緩存

目前Findbugs支持除了java 8之外的全部版本編譯的字節碼文件分析。 安全

Findbugs不只提供了可視化界面,還有Idea,Eclipse插件。 less

Findbugs有谷歌和SUM/(Oracle)支持,在JDK源碼編譯中,依賴了Findbugs對JDK源碼的檢查。也就是說,雖然能夠自由編譯JDK,可是若是修改後的代碼太爛,不能經過Findbugs的檢查,同樣不能經過編譯。 eclipse

使用

項目地址:http://findbugs.sourceforge.net/ ide

Findbugs支持命令行,ant,可視化界面和IDE插件方式運行,以IDEA的插件使用爲例。 工具

Eclipse插件安裝地址:http://findbugs.cs.umd.edu/eclipse/ oop

IDEA插件安裝地址:http://plugins.jetbrains.com/plugin/3847 性能

截圖

支持類型

在Findbugs中能找到下面類型的bug(有些不算是bug,應該說是很差的實踐)。 .net

Cateory
Number
Samples

Correctness

142

Illegal format string

Null value is guaranteed to be dereferenced

Call to equals() comparing unrelated class and interface

Bad practice

84

Confusing method names

Method may fail to close stream

Comparison of String parameter using == or !=

Dodgy code

71

Useless control flow

Integer remainder modulo 1

Redundant null check of value known to be null

Multithreaded Correctness

45

A thread was created using the default empty run method

Class's writeObject() method is synchronized but nothing else is

Performance

27

Method concatenates strings using + in a loop

Method invokes inefficient Boolean constructor

Malicious Code Vulnerability

15

Finalizer should be protected, not public

Field isn't final and can't be protected from malicious code

Security

11

Hardcoded constant database password

A prepared statement is generated from a variable String

Experimental

3

Method may fail to clean up stream or resource

Internationalization

2

Consider using Locale parameterized version of invoked method

發現代碼中的問題
性能:

低效的迭代器:/images/java/performance_1_zps684644d6.png

修改後:

for (Integer groupKey : groupList.keySet()) 
    insertGroupedList(groupKey);
}

裝箱/拆箱/images/java/performance_2_zpsfa307a6d.png0L在java.lang.Long中是有緩存的,因此常量0L先拆箱成小long,而後賦值給agengId的時候裝箱成大Long,兩次操做就是沒有必要的。

修改後:

agentId = (agentId == null) ? Long.valueOf(0) : agentId;

靜態變量:

/images/java/performance_3_zps953e82e7.png

這個常量是在初始化的時候賦值的,在內存中沒有必要存在多份,能夠聲明成static。

內部類,何不靜態?

/images/java/performance_4_zps26c9d77b.png

MuFlightInfoDO是MuFlightFareQuery的內部類,MuFlightInfoDO的實例保存了一份建立它的類(MuFlightFareQuery)的引用,這樣不只使MuFlightInfoDO類佔用更大的空間,並且是外部的MuFlightFareQuery生命週期更長了。

很差的實踐:

忽略異常:

/images/java/bp_1_zps8cbf8e46.png

集合使用removeAll來清理:

/images/java/bp_2_zps02c6d731.png

直接調用clear()或者是個bug?

流程:

/images/java/bp_3_zps5fb05951.png

else if裏面有沒任何代碼,考慮刪除。

集合:

/images/java/bp_4_zps48cb693d.png

hsfServices 聲明成map:ConcurrentHashMap<String,HSFSpringConsumerBean hsfServices>

在這裏hsfServices.contains(key)參數是String類型,可是聲明的map是HSFSpringConsumerBean類型,應該永遠不會返回true,應該是containsKey吧?

equal類型不匹配:

/images/java/QQ622A56FE20131124134350_zps59c66a2c.png

dfare.getAgentSupportType().equals(AgentSupportType.ONE) 左邊Integer,右邊enum。

線程安全:

DateFormat

/images/java/qq_zps9b7f1f9c.pngDateFormat不是線程安裝的,在這裏聲明爲類成員,會有問題。

總結

有些代碼問題在人爲的review的時候很難發現,若是上線了會有很大的隱患,雖然當時沒有出現bug。利用Findbugs在提交代碼的時候本身進行review。讓你的代碼出更少的bug。

Keep the bar green, keep you code clean.

相關文章
相關標籤/搜索