Eclipse findbugs外掛使用及簡單介紹
FindBugs是一個可以在Java程式中發現Bugs的程式。它是專門用來尋找處於"Bug Patterns"列表中的程式碼的。Bug Patterns指很有可能是錯誤的程式碼的例項。
開啟Bug Details檢視Windows => Show View => Other… => FindBugs => BugDetails。
在Package Explorer或Navigator檢視中,選中你的Java專案,右鍵,可以看到"Find Bugs"選單項,子選單項裡有"FindBugs"和"Clear Bug Markers"兩項內容,如下圖所示:
我們建立一個簡單的測試檔案Test.java 內容如下:
<span style="font-family:SimSun;font-size:12px;"></span><table style="background: rgb(230, 230, 230); border-collapse: collapse;" border="0"><colgroup><col style="width: 400px;" /></colgroup><tbody valign="top"><tr><td valign="middle" style="padding: 2px; border: 0.75pt outset currentColor;"><p><span style="font-family:SimSun;font-size:12px;">public class Test </span><span style="font-family:SimSun;font-size:12px;">{ </span></p><p><span style="font-family:SimSun;font-size:12px;"> private String[] name; </span></p><p><span style="font-family:SimSun;font-size:12px;"> public String[] getName() </span><span style="font-family:SimSun;font-size:12px;">{ </span></p><p><span style="font-family:SimSun;font-size:12px;"> return name; </span></p><p><span style="font-family:SimSun;font-size:12px;"> } </span></p><p><span style="font-family:SimSun;font-size:12px;"> public void setName(String[] name) </span><span style="font-family:SimSun;font-size:12px;">{ </span></p><p><span style="font-family:SimSun;font-size:12px;"> this.name = name; </span></p><p><span style="font-family:SimSun;font-size:12px;"> } </span></p><p><span style="font-family:SimSun;font-size:12px;">} </span></p><p><span style="font-family:SimSun;font-size:12px;"></span> </p></td></tr></tbody></table>
我們點中"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屬性。