Eclipse findbugs找出的bug案例说明
2.以下都是我使用findbug在公司项目中找到的一些bug,这里做一些中文的简短说明(不是翻译)
3.篇幅可能会有点长,阅读时,大家可以通过ctrl+f根据关键字查找自己相关的bug
BUG-0001
Bug: Field only ever set to null: com.bettersoft.admin.BtCorpManager.ps
All writes to this field are of the constant value null, and thus all reads of the field will return null. Check for errors, or remove it if it is useless.
Confidence: Normal, Rank: Troubling (12)
Pattern: UWF_NULL_FIELD
Type: UwF, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
7
8
9
10
|
public
class
BtCorpManager { private
BtCorp btcorp= null ; private
Connection con = null ; private
Statement st = null ; private
PreparedStatement ps = null ; private
ResultSet rs = null ; private
void
setConnection(String centerno) throws
Exception{ //con
= DBManager.getConnection(centerno); con
= DBManager.getConnection(); } |
解释说明:在BtCorpManager类里面定了一个私有的成员变量PreparedStatement ps,但是这个成员变量ps在实例范围内没有得到任何的初始化(采用默认的构造方法),始终为null,所以在实例范围内使用该成员变量时,如果不先对其进行初始化操作或者无意识的行为忘了初始化操作,那肯定是要报空指针异常,所以这无疑是一个bug
推荐修改: 自己看着办
BUG-0002
Bug: Nullcheck of form at line 36 of value previously dereferenced in com.bettersoft.admin.CorpEditAction.execute(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse)
A value is checked here to see whether it is null, but this value can't be null because it was previously dereferenced and if it were null a null pointer exception would have occurred at the earlier dereference. Essentially, this code and the previous dereference disagree as to whether this value is allowed to be null. Either the check is redundant or the previous dereference is erroneous.
Confidence: High, Rank: Scary (9)
Pattern: RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE
Type: RCN, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws
Exception { //throw
new UnsupportedOperationException("Method is not implemented"); ActionErrors
errors = new
ActionErrors(); CreateCorpActionForm
createCorp = new
CreateCorpActionForm(); createCorp
= (CreateCorpActionForm)form; CreateCorpActionForm
webcorp= new
CreateCorpActionForm(); BudgetWebcorpManager
budgetWebcorpManager= new
BudgetWebcorpManager(); webcorp=budgetWebcorpManager.getCWebcorp(createCorp.getId()); createCorp.setFbsaddapproveid(webcorp.getFbsaddapproveid()); createCorp.setFbsinputapproveid(webcorp.getFbsinputapproveid()); createCorp.setFbsprocessapproveid(webcorp.getFbsprocessapproveid()); boolean
b= false ; if (createCorp!= null ){ |
1
|
if (createCorp!= null ){ |
1
|
createCorp
= (CreateCorpActionForm)form; |
是不会导致createCorp指向空的,唯一的缺陷就是之前的new操作是多余的。
推荐修改:自己看着办
BUG-0003
Bug: con is null guaranteed to be dereferenced in com.bettersoft.admin.leftAction.getLeft(int, String, String) on exception path
There is a statement or branch on an exception path that if executed guarantees that a value is null at this point, and that value that is guaranteed to be dereferenced (except on forward paths involving runtime exceptions).
Confidence: Normal, Rank: (Troubling 11)
Pattern: NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH
Type: NP, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
finally { try { if (rs
!= null ) rs.close(); if (ps!= null ) ps.close(); con.close(); } catch (Exception
ee) { ee.printStackTrace(); } } |
推荐修改:自己看着办
BUG-0004
Bug: Possible null pointer dereference of dbVersion in com.bettersoft.admin.LoginAction.loadVersion(HttpServletRequest, ActionErrors) on exception path
A reference value which is null on some exception control path is dereferenced here. This may lead to aNullPointerExceptionwhen the code is executed. Note that because FindBugs currently does not prune infeasible exception paths, this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.
Confidence: Normal, Rank: Troubling (11)
Pattern: NP_NULL_ON_SOME_PATH_EXCEPTION
Type: NP, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
VersionInfo
dbVersion = null ; try
{ con
= DBManager.getConnection(); dbVersion
= vm.getVersionInfo(con); }
catch
(Exception e) { //
TODO Auto-generated catch block e.printStackTrace(); }
finally
{ try
{ con.close(); }
catch
(SQLException e) { //
TODO Auto-generated catch block e.printStackTrace(); } } if
(dbVersion.equals(programVersion)) { programVersion.setCorrent( true ); }
else
{ programVersion.setCorrent( false ); } |
1
|
dbVersion.equals(programVersion) |
BUG-0005
Bug: Dead store to am in com.bettersoft.approve.action.CheckAction.execute(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse)
This instruction assigns a value to a local variable, but the value is not read or used in any subsequent instruction. Often, this indicates an error, because the value computed is never used.
Note that Sun's javac compiler often generates dead stores for final local variables. Because FindBugs is a bytecode-based tool, there is no easy way to eliminate these false positives.
Confidence: High, Rank: Of Concern (15)
Pattern: DLS_DEAD_LOCAL_STORE
Type: DLS, Category: STYLE (Dodgy code)
代码片段:
1
|
ApproveManager
am = new
ApproveManager(); |
BUG-0006
Bug: The class name com.bettersoft.approve.form.BtWebCorp shadows the simple name of the superclass com.bettersoft.admin.BtWebCorp
This class has a simple name that is identical to that of its superclass, except that its superclass is in a different package (e.g.,alpha.Fooextendsbeta.Foo). This can be exceptionally confusing, create lots of situations in which you have to look at import statements to resolve references and creates many opportunities to accidently define methods that do not override methods in their superclasses.
Confidence: High, Rank: Troubling (14)
Pattern: NM_SAME_SIMPLE_NAME_AS_SUPERCLASS
Type: Nm, Category: BAD_PRACTICE (Bad practice)
1
2
3
|
public
class
BtWebCorp extends
com.bettersoft.admin.BtWebCorp{ } |
BUG-0007
Bug: Comparison of String objects using == or != in com.byttersoft.admin.persistence.dao.MessageOpenDao.addOpenSave(MessageOpenForm)
This code comparesjava.lang.Stringobjects for reference equality using the == or != operators. Unless both strings are either constants in a source file, or have been interned using theString.intern()method, the same string value may be represented by two different String objects. Consider using theequals(Object)method instead.
Confidence: Normal, Rank: Troubling (11)
Pattern: ES_COMPARING_STRINGS_WITH_EQ
Type: ES, Category: BAD_PRACTICE (Bad practice)
1
2
3
4
5
|
if (id== null
|| id== "" ){ sql
= "insert
into xx values (1,?,?,?)" ; } else { sql
= "insert
into xx values ((select max(id) + 1 from xx),?,?,?)" ; } |
BUG-0008
Bug: Call to String.equals(Double) in com.byttersoft.amm.util.BalanceInterzoneRateUtil.formatRate(Double)
This method calls equals(Object) on two references of different class types with no common subclasses. Therefore, the objects being compared are unlikely to be members of the same class at runtime (unless some application classes were not analyzed, or dynamic class loading can occur at runtime). According to the contract of equals(), objects of different classes should always compare as unequal; therefore, according to the contract defined by java.lang.Object.equals(Object), the result of this comparison will always be false at runtime.
Confidence: High, Rank: Scariest (1)
Pattern: EC_UNRELATED_TYPES
Type: EC, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
|
private
static
String formatRate(Double r){ if (r== null
|| ( "undefined" ).equals(r)){ return
null ; } |
1
|
( "undefined" ).equals(r) |
BUG-0009
Bug: Class com.byttersoft.util.CertInfo defines non-transient non-serializable instance field subjectDnAttr
This Serializable class defines a non-primitive instance field which is neither transient, Serializable, orjava.lang.Object, and does not appear to implement theExternalizableinterface or thereadObject()andwriteObject()methods. Objects of this class will not be deserialized correctly if a non-Serializable object is stored in this field.
Confidence: High, Rank: Troubling (14)
Pattern: SE_BAD_FIELD
Type: Se, Category: BAD_PRACTICE (Bad practice)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
class
CertInfo implements
java.io.Serializable { private
String subjectDN= "" ; private
String issuerDN= "" ; private
String notAfterDate= "" ; private
String notBeforeDate= "" ; private
String serialNumber= "" ; private
String sigAlgName= "" ; private
String sigAlgOID= "" ; private
String version= "" ; private
String publicKeyFormat= "" ; private
String publicKeyAlgorithm= "" ; private
Names subjectDnAttr= null ; } public
class
Names {}<span></span> |
BUG-0010
Bug: Dead store to corpGourps rather than field with same name in com.byttersoft.admin.form.CorpGroupsForm.setCorpGourps(CorpGourps)
This instruction assigns a value to a local variable, but the value is not read or used in any subsequent instruction. Often, this indicates an error, because the value computed is never used. There is a field with the same name as the local variable. Did you mean to assign to that variable instead?
Confidence: High, Rank: Scary (9)
Pattern: DLS_DEAD_LOCAL_STORE_SHADOWS_FIELD
Type: DLS, Category: STYLE (Dodgy code)
1
2
3
|
public
void
setCorpGourps(CorpGourps corpGourps) { corpGourps
= corpGourps; } |
BUG-0011
Bug: Invocation of toString on labelValue in com.byttersoft.approve.persistence.dao.MesAppDao.getMapByPara(String)
The code invokes toString on an array, which will generate a fairly useless result such as [C@16f0472. Consider using Arrays.toString to convert the array into a readable String that gives the contents of the array. See Programming Puzzlers, chapter 3, puzzle 12.
Confidence: Normal, Rank: Troubling (10)
Pattern: DMI_INVOKING_TOSTRING_ON_ARRAY
Type: USELESS_STRING, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
7
8
9
10
|
for
(String parameter : parameters) { String[]
labelValue = parameter.split( "=" ); if
(labelValue.length == 2 )
{ String
key = labelValue[ 0 ]; String
value = labelValue[ 1 ]; hashMap.put(key,
value); }
else
{ logger.debug( "参数
"
+ labelValue + "
配置错误。" ); } } |
BUG-0012
Bug: Write to static field com.byttersoft.admin.service.BtSysResService.map from instance method com.byttersoft.admin.service.BtSysResService.hashCatchOfSysRes(boolean)
This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice.
Confidence: High, Rank: Of Concern (15)
Pattern: ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD
Type: ST, Category: STYLE (Dodgy code)
1
2
3
4
5
6
7
8
9
10
11
|
static
Map<String, BtSysRes> map = new
HashMap<String, BtSysRes>(); public
Map<String, BtSysRes> hashCatchOfSysRes( boolean
isRefresh) { if (isRefresh
== true ){ map
= hashCatchOfSysRes(); } else { if (map
== null
|| map.isEmpty()){ map
= hashCatchOfSysRes(); } } return
map; } |
推荐修改:将该方法改为类方法
BUG-0013
Bug: Unwritten field: com.byttersoft.admin.service.importservice.ImportServices.bank
This field is never written. All reads of it will return the default value. Check for errors (should it have been initialized?), or remove it if it is useless.
Confidence: Normal, Rank: Troubling (12)
Pattern: UWF_UNWRITTEN_FIELD
Type: UwF, Category: CORRECTNESS (Correctness)
代码片段:
1
2
3
4
5
6
|
public
class
ImportServices { private
IBankAccServices bank; public
IBankAccServices getBank() { return
bank; } } |
BUG-0014
Bug: There is an apparent infinite recursive loop in com.byttersoft.amm.dao.impl.CheckLoanOrProvideInfoDaoImpl.addBatch(List)
This method unconditionally invokes itself. This would seem to indicate an infinite recursive loop that will result in a stack overflow.
Confidence: High, Rank: Scary (9)
Pattern: IL_INFINITE_RECURSIVE_LOOP
Type: IL, Category: CORRECTNESS (Correctness)
1
2
3
|
public
void
addBatch(List<CmsPLoanToBean> cmsPLoanBeans) { this .addBatch(cmsPLoanBeans); } |