FindBug检查问题指南.docx
《FindBug检查问题指南.docx》由会员分享,可在线阅读,更多相关《FindBug检查问题指南.docx(17页珍藏版)》请在冰豆网上搜索。
![FindBug检查问题指南.docx](https://file1.bdocx.com/fileroot1/2023-1/27/39444af7-3e62-4b4c-b882-ab45d360b46c/39444af7-3e62-4b4c-b882-ab45d360b46c1.gif)
FindBug检查问题指南
FindBugs常见问题指南
1 ComparisonofStringobjectsusing==or!
=
例,overrideequals方法时容易犯错
Java代码
1.if(this.topic !
= key.getTopic())
2. return false;
2DeadstoretonewStatusRecord
定义局部变量后没有引用
3InvocationoftoStringonvalues
直接调用数组的toString方法
Java代码
1.public Query createQuery(String hql, Object values[],Session session){
2. logger.debug(values);
3. logger.debug((new StringBuilder()).append("hql=[").append(hql).append("] ").append(((Object)
4.
5.}
publicQuerycreateQuery(Stringhql,Objectvalues[],Sessionsession){
logger.debug(values);
logger.debug((newStringBuilder()).append("hql=[").append(hql).append("]").append(((Object)
}
正确的例子,调用Arrays.toString()和Arrays.deepToString()方法。
Java代码
1. import java.util.Arrays;
2.
3.class A{
4.
5.}
6.class B{
7. @Override
8. public String toString() {
9. return "BBBBB";
10. }
11.}
12.public class Test {
13. public static void main(String[] args) {
14.
15.
16. Object [] a = {new Integer(0),new Boolean(true),true,new A(),new B()};
17.
18. Object[][]b ={{new A(),new B()},{new A(),new B()},{new A(),new B()}};
19. System.out.println(Arrays.deepToString(b));
20.
21. }
22.}
4ignoresexceptionalreturnvalueofjava.io.File.mkdirs()
忽略了返回值,应当含有返回值
Java代码
1.public void initFolder() {
2. (!
exitDir.isDirectory()) {
3. exitDir.mkdirs();
4. logger.info("===Finishing create exit trade image folder!
====");
5.} publicvoidinitFolder(){
if(!
exitDir.isDirectory()){
exitDir.mkdirs();
logger.info("===Finishingcreateexittradeimagefolder!
====");
}
}
Thismethodreturnsavaluethatisnotchecked.Thereturnvalueshouldbecheckedsinceitcanindicateanunusualorunexpectedfunctionexecution.Forexample,theFile.delete()methodreturnsfalseifthefilecouldnotbesuccessfullydeleted(ratherthanthrowinganException).Ifyoudon'tchecktheresult,youwon'tnoticeifthemethodinvocationsignalsunexpectedbehaviorbyreturninganatypicalreturnvalue.
5不使用newString()定义空的字符串
Java代码
1.String alarmCodeCond = new String();
StringalarmCodeCond=newString();
应当
Java代码
1.String alarmCodeCond = "";
6invokesinefficientnewShort(short)constructor;useShort.valueOf(short)instead
JVM缓存数字常量
Java代码
1.Short aShort = new Short(12);
ShortaShort=newShort(12);
应当
Java代码
1.Short aShort = Short.valueOf(12);
7方法命名习惯,首字母小写
ThemethodnameLaneHandShakeService(Short)doesn'tstartwithalowercaseletter
Methodsshouldbeverbs,inmixedcasewiththefirstletterlowercase,withthefirstletterofeachinternalwordcapitalized.
8 一个primtive的类型的值经过box后马上unbox
Primitivevalueisboxedthenunboxedtoperformprimitivecoercion
Java代码
1.exitRecord.setEnOperatorId(new Long(transactRecord.getEnoperatorID()).intValue());
exitRecord.setEnOperatorId(newLong(transactRecord.getEnoperatorID()).intValue());
应当直接强制类型转换
Java代码
1.exitRecord.setEnOperatorId((int)transactRecord.getEnoperatorID());
StringalarmCodeCond="";
9Calltoequals()comparingdifferenttypes
使用equals()方法比较不同的类,
反例
Java代码
1.StringBuilder builder = new StringBuilder("nihao");
2.String string = "nihao";
3.builder.equals(string);
10 Checkforoddnessthatwon'tworkfornegativenumbers
检查奇数的方法:
反例
Java代码
1.if (i % 2 == 1) {
2. //...
3.} if(i%2==1){
//...
}
Thecodeusesx%2==1tochecktoseeifavalueisodd,butthiswon'tworkfornegativenumbers(e.g.,(-5)%2==-1).Ifthiscodeisintendingtocheckforoddness,considerusingx&1==1,orx%2!
=0.
11Loadofknownnullvalue,null值的不当使用
反例:
Java代码
1.if (devIds == null && devIds.size() == 0) { //... }
if(devIds==null&&devIds.size()==0){//...}
Java代码
1.if (null !
= tempList || tempList.size() !
= 0) {
2. //...
3.} if(null!
=tempList||tempList.size()!
=0){
//...
}
Java代码
1.if (batchNo == null) {
2. throw new Exception("the No. " + batchNo
3. + " is not exists!
");
4. }
12 Methodcallpassesnullfornonnullparameter
对参数为null的情况没做处理
例:
Java代码
1.public void method1() {
2. String ip = null;
3. try {
4. ip = InetAddress.getLocalHost().getHostAddress();
5. } catch (UnknownHostException e) {
6. e.printStackTrace();
7. }
8. long ipCount = countIpAddress(ip); // 可能会传入空引用
9. //...
10.}
11.
12. long countIpAddress(String ip) {
13. long ipNum = 0;
14. String[] ipArray = ip.split("\\.");
15.}
publicvoidmethod1(){
Stringip=null;
try{
ip=InetAddress.getLocalHost().getHostAddress();
}catch(UnknownHostExceptione){
e.printStackTrace();
}
longipCount=countIpAddress(ip);//可能会传入空引用
//...
}
longcountIpAddress(Stringip){
longipNum=0;
String[]ipArray=ip.split("\\.");
}
修改后:
Java代码
1.public void method1() {
2. String ip = null;
3. try {
4. ip = InetAddress.getLocalHost().getHostAddress();
5. } catch (UnknownHostException e) {
6. e.printStackTrace();
7. }
8. long ipCount = countIpAddress(ip); // 可能会传入空引用
9. //...
10.}
11.
12. long countIpAddress(String ip) {
13. long ipNum = 0;
14. if (ip == null) {
15. return 0; //或者抛出异常
16. }
17. String[] ipArray = ip.split("\\.");
18. //...
19.}
publicvoidmethod1(){
Stringip=null;
try{
ip=InetAddress.getLocalHost().getHostAddress();
}catch(UnknownHostExceptione){
e.printStackTrace();
}
longipCount=countIpAddress(ip);//可能会传入空引用
//...
}
longcountIpAddress(Stringip){
longipNum=0;
if(ip==null){
return0;//或者抛出异常
}
String[]ipArray=ip.split("\\.");
//...
}
注意:
函数入口需要交验入参的合法性。
13Methodconcatenatesstringsusing+inaloop
在循环里使用字符串连接,效率低,应该使用StringBuilder/StringBuffer
例:
Java代码
1.String writeData = "";
2.for (int i = 0; i < 10; i++) {
3. writeData = writeData + "a";
4.}
14Methodmayfailtoclosedatabaseresource
没有释放数据库资源
Java代码
1.public ResultSet callProcedure(String procedure) {
2. Session ses = getSessionForUpdate();
3. ResultSet rs = null;
4. try {
5. Connection conn = ses.connection();
6. conn.setAutoCommit(false);
7. CallableStatement statement = conn.prepareCall(procedure); //may fail to close CallableStatement
8.
9. rs = statement.executeQuery();
10. mit();
11.
12. } catch (Exception e) {
13. e.printStackTrace();
14. } finally {
15. try {
16. ses.close();
17. } catch (SQLException e) {
18. throw e;
19. }
20. }
21. return rs;
22.}
publicResultSetcallProcedure(Stringprocedure){
Sessionses=getSessionForUpdate();
ResultSetrs=null;
try{
Connectionconn=ses.connection();
conn.setAutoCommit(false);
CallableStatementstatement=conn.prepareCall(procedure);//mayfailtocloseCallableStatement
rs=statement.executeQuery();
mit();
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
ses.close();
}catch(SQLExceptione){
throwe;
}
}
returnrs;
}
应当修改为:
Java代码
1.public ResultSet callProcedure(String procedure) {
2. Session ses = getSessionForUpdate();
3. ResultSet rs = null;
4. CallableStatement statement = null;
5. try {
6. Connection conn = ses.connection();
7. conn.setAutoCommit(false);
8. statement = conn.prepareCall(procedure);
9.
10. rs = statement.executeQuery();
11. mit();
12.
13. } catch (Exception e) {
14. e.printStackTrace();
15. } finally {
16. try {
17. statement.close();
18. ses.close();
19. } catch (SQLException e) {
20. e.printStackTrace();
21. }
22.
23. }
24. return rs;
25.}
15Methodmayfailtoclosestream
没有关闭流,可能会导致文件描述符泄露,应该在finally中关闭
例:
Java代码
1.try {
2. FileInputStream in = new FileInputStream(file);
3. InputStreamReader inputStreamReader = new InputStreamReader(in);
4. BufferedReader reader = new BufferedReader(inputStreamReader);
5. //...
6.
7. in.close();
8. inputStreamReader.close();
9. reader.close();
10.} catch (IOException e) {
11.
12.}
try{
FileInputStreamin=newFileInputStream(file);
InputStreamReaderinputStreamReader=newInputStreamReader(in);
BufferedReaderreader=newBufferedReader(inputStreamReader);
//...
in.close();
inputStreamReader.close();
reader.close();
}catch(IOExceptione){
}
修改为:
Java代码
1.FileInputStream in = null;
2.InputStreamReader inputStreamReader = null;
3.BufferedReader reader = null;
4.try {
5. in = new FileInputStream(file);
6. inputStreamReader = new InputStreamReader(in);
7. reader = new BufferedReader(inputStreamReader);
8. // ...
9.
10.} catch (IOException e) {
11.
12.}