Findbugs使用說明
1 用途
FindBugs 是一個java bytecode靜態分析工具,它可以幫助java工程師提高代碼質量以及排除隱含的缺陷。
FindBugs檢查類或者 JAR 文件,將字節碼與一組缺陷模式進行對比以發現可能的問題。
有了靜態分析工具,就可以在不實際運行程序的情況對軟件進行分析。FindBugs不是通過分析類文件的形式或結構來確定程序的意圖,而是通常使用 Visitor 模式進行分析(Visitor 模式的更多信息)。
2 安裝
目前findbugs最新的版本是1.3.9,
2.1 Eclipse插件的安裝
環境要求,Findbugs要求Eclipse 3.4 以上的版本,JRE/JDK 1.5.0以上的版本。
步驟,將edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821.zip解壓到Eclipse的 "plugins"子目錄下,這樣就可以在 <eclipse_install_dir>/plugins/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821/下看到FindBugs logo圖片findbugs.png。
啟動Eclipse 然后選擇 Help → About Eclipse Platform → Plug-in Details,你應該找到 "FindBugs Plug-in"。
3 使用
啟動
選中java工程,點擊鼠標右鍵,選擇名為“Find Bugs”的菜單,FindBugs開始運行,問題指示器將指向根據bug模式識別出來的潛在問題代碼位置。
可選項定制
你還可以通過java工程的屬性對話框來定制findbugs的運行方式,可選項包括:
控制"Run FindBugs Automatically" 開關的checkbox。 選中時, FindBugs 將在每次修改java類后啟動運行。
選擇最小告警優先級和Bug類別。這些選項將選擇哪些警告被顯示。例如,如果你選擇"Medium",只有Medium 和 High priority 警告將被顯示。近似地,如果你未選中 "Style" checkbox,Style類的警告信息將不會被顯示。
選擇探測器。這個列表允許你選擇你想在工程中使用的探測器。
4 配套的Bug模式解釋
為了有針對性的使用這個工具,減少bug的誤報,提高使用效率,我們選擇了10個左右的bug模式,下面就是對這10個模式的解釋。
這些bug可能會引起程序的性能或邏輯問題.
需要說明的是,findbugs能檢測的bug pattern遠不僅于此,甚至可以定制自己的探測器,因此,這個文檔會不斷擴充,同時,也歡迎大家不斷探索和分享使用實踐.
4.1 ES_COMPARING_PARAMETER_STRING_WITH_EQ
ES: Comparison of String parameter using == or != (ES_COMPARING_PARAMETER_STRING_WITH_EQ)
This code compares a java.lang.String parameter for reference equality using the == or != operators. Requiring callers to pass only String constants or interned strings to a method is unnecessarily fragile, and rarely leads to measurable performance gains. Consider using the equals(Object) method instead.
使用 == 或者 != 來比較字符串或interned字符串,不會獲得顯著的性能提升,同時并不可靠,請考慮使用equals()方法。
4.2 HE_EQUALS_NO_HASHCODE
HE: Class defines equals() but not hashCode() (HE_EQUALS_NO_HASHCODE)
This class overrides equals(Object), but does not override hashCode(). Therefore, the class may violate the invariant that equal objects must have equal hashcodes.
類定義了equals()方法但沒有重寫hashCode()方法,這樣違背了相同對象必須具有相同的hashcodes的原則
4.3 IT_NO_SUCH_ELEMENT
It: Iterator next() method can't throw NoSuchElement exception (IT_NO_SUCH_ELEMENT)
This class implements the java.util.Iterator interface. However, its next() method is not capable of throwing java.util.NoSuchElementException. The next() method should be changed so it throws NoSuchElementException if is called when there are no more elements to return.
迭代器Iterator無法拋出NoSuchElement異常,類實現了java.util.Iterator接口,但是next()方法無法拋出java.util.NoSuchElementException異常,因此,next()方法應該做如此修改,當被調用時,如果沒有element返回,則拋出NoSuchElementException異常
4.4 J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION
J2EE: Store of non serializable object into HttpSession (J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION)
This code seems to be storing a non-serializable object into an HttpSession. If this session is passivated or migrated, an error will result.
將沒有實現serializable的對象放到HttpSession中,當這個session被鈍化和遷移時,將會產生錯誤,建議放到HttpSession中的對象都實現serializable接口。
4.5 ODR_OPEN_DATABASE_RESOURCE
ODR: Method may fail to close database resource (ODR_OPEN_DATABASE_RESOURCE)
The method creates a database resource (such as a database connection or row set), does not assign it to any fields, pass it to other methods, or return it, and does not appear to close the object on all paths out of the method. Failure to close database resources on all paths out of a method may result in poor performance, and could cause the application to have problems communicating with the database.
方法可能未關閉數據庫資源,未關閉數據庫資源將會導致性能變差,還可能引起應用與服務器間的通訊問題。
4.6 OS_OPEN_STREAM
OS: Method may fail to close stream (OS_OPEN_STREAM)
The method creates an IO stream object, does not assign it to any fields, pass it to other methods that might close it, or return it, and does not appear to close the stream on all paths out of the method. This may result in a file descriptor leak. It is generally a good idea to use a finally block to ensure that streams are closed.
方法可能未關閉stream,方法產生了一個IO流,卻未關閉,將會導致文件描繪符的泄漏,建議使用finally block來確保io stream被關閉。
4.7 DMI_CALLING_NEXT_FROM_HASNEXT
DMI: hasNext method invokes next (DMI_CALLING_NEXT_FROM_HASNEXT)
The hasNext() method invokes the next() method. This is almost certainly wrong, since the hasNext() method is not supposed to change the state of the iterator, and the next method is supposed to change the state of the iterator.
4.8 IL_INFINITE_LOOP
IL: An apparent infinite loop (IL_INFINITE_LOOP)
This loop doesn't seem to have a way to terminate (other than by perhaps throwing an exception).
明顯的無限循環.
4.9 IL_INFINITE_RECURSIVE_LOOP
IL: An apparent infinite recursive loop (IL_INFINITE_RECURSIVE_LOOP)
This method unconditionally invokes itself. This would seem to indicate an infinite recursive loop that will result in a stack overflow.
明顯的無限迭代循環,將導致堆棧溢出.
4.10 WMI_WRONG_MAP_ITERATOR
WMI: Inefficient use of keySet iterator instead of entrySet iterator (WMI_WRONG_MAP_ITERATOR)
This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) lookup.
使用了keySet iterator和Map.get(key)來獲取Map值,這種方式效率低,建議使用entrySet的iterator效率更高.
4.11 IM_BAD_CHECK_FOR_ODD
IM: Check for oddness that won't work for negative numbers (IM_BAD_CHECK_FOR_ODD)
The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
奇偶檢測邏輯,未考慮負數情況.
新聞熱點
疑難解答