IntelliJ IDEA 代碼檢查規範QAPlug

轉自:http://blog.csdn.net/jizi7618937/article/details/51500725

Avoid Array Loops

數組之間的拷貝使用System.arrayCopy更加高效java

byte[] ReceiveBytes = new byte[length1+ length2];
for (int i = 0; i < length1; i++) {
    ReceiveBytes[i] =ReceiveBytes_temp1[i];
}
正則表達式

Big Integer Instantiation

 避免建立已經存在的Big Integer對象 ,如:(BigDecimal.ZERO,BigDecimal.ONE, BigDecimal.TEN)spring

Boolean Instantiation

避免建立已經存在的Boolean 對象;如:Boolean.TRUE, Boolean.FALSEexpress

Final field Could Be Static

有Final修飾符的成員變量必須是靜態的數組

Explicitly invokes garbage collection

避免顯示調用垃圾回收緩存

Inefficient use of keySet iterator instead of entrySetiterator

低效利用使用keySet迭代器而不是entrySet迭代器。安全

使用entrySet效率會比keySet高app

for (String key : map.keySet()) {框架

//to do some thingless

}

for (Entry entry : map.entrySet()) {

//to do some thing

}

Method Concatenates String Using + In Loop

避免在循環中使用「+」 鏈接字符串。使用Stringbuffer 或Stringbuilder

private method is never called

定義爲Private類型方法從未被調用,應該被刪除

Use ArrayList Instead Of Vector

使用ArrayList 替換Vector

Use Arrays As List

若是從數組轉換成一個List,用Arrays. AsList() 替換遍歷數組的形式轉換

UnnecessarilyLocal Before Return

避免建立無用的局部變量,如:

String s = getxx();

return s;

直接替換爲return getxx();

Use IndexOf Char

當參數是單個字符的時候使用 String.indexOf(char)替換String.indexOf(String)

好比:用s.indexOf(‘a‘) 代替s.indexOf(「a」)

Method Invokes inefficient new String() constructor

如:String s = new String();

正確寫法 String s = 「」;

Method Invokes inefficient new String(string) constructor

如:String s = new String(「test」);

正確寫法 String s = 「test」;

Method Invokes inefficient Number constructor

Long, Integer, Short, Character, and Byte 使用valueOf代替直接實例化

Number 類型從-128 到127會緩存到常量池,能夠節省內存

Integer i = new Integer(4);
Integer j = new Integer(4);
System.out.println(i==j);// false
i = Integer.valueOf(4);
j = Integer.valueOf(4);
System.out.println(i==j); // true
i = Integer.valueOf(128);
j = Integer.valueOf(128);

 System.out.println(i==j);//false

Primitive value is boxed then unboxed to perform primitivecoercion

對原始值進行裝箱而後當即把它強制轉換爲另一種原始類型。例如:

new Double(d).intValue()應該直接進行強制轉換例如:(int)d

Class defines equals() but not hashCode()

Unused import

無用的包導入

Unused local variable

無用的局部變量

Unused formal parameter

未用的常規參數:避免傳遞給方法或構造器不使用的參數

TODO Comment

代碼中包含TODO註釋

Empty Statement

避免使用空代碼塊

Don't Import Java.Lang

Collapsible If Statements

有時候兩個 if 語句能夠經過布爾短路操做符分隔條件表達式組合成一條語句

如:

If(a==b){

  If(c==1){

//do some thing

}

}

Avoid Decimal Literals In BigDecimal Constructor

避免在 BigDecimal 類型的構造方法中用小數類型的字面量:人們經常以

爲」new BigDecimal(0.1)」能精確等於 0.1, 其實否則,它等於「 0. 1000000000000000055511151231257827021181583404541015625 」,這 種情況的緣由是 0.1 不能精確的表示雙精度類型,所以,傳入構造器的 long 類型不等於 0.1 ,而傳入 String 類型的構造器 new BigDecimal(「0.1」) 能夠精確等於 0.1, 故推薦這種情形時用 String 類型的構造器

Broken Null Check

破壞空檢查:若是自身拋出空指針異常空檢查就會遭到破壞,好比你使用 || 代替 && ,反之亦然。

 

if (string!=null ||!string.equals("")) {   // 這裏應該是&&

return string;

}

Close Resource

關閉資源:確保這些資源(譬如:Connection,Statement, ResultSet )總在使用後被關閉

Compare Objects With Equals

對象相等性比較:使用 equals()比較對象的引用,避免使用」==」來比較

 

"." used for regular expression

String的split,replaceAll等方法傳遞的參數是正則表達式,正則表達式自己用到的字符須要轉義,如:句點符號「.」,美圓符號「$」,乘方符號「^」,大括號「{}」,方括號「[]」,圓括號「()」,豎線「|」,星號「*」,加號「+」,問號「?」等等,這些須要在前面加上「\\」轉義符。

如:s = s.replaceAll(".", "/"); 應該使用s =s.replaceAll("\\.", "/");

An apparent infinite loop

 

 

明顯的無限循環

An apparent infinite recursive loop

明顯的無限迭代循環,將致使堆棧溢出

 

 

Equals And HashCode

重寫equals 後必須重寫hashCode

Equals Null

避免equals()方法和 null 比較

Junit TestShould Include Assert

單元測試必須包含斷言,而不是簡單的打印結果後看輸出。

Useless Operation On Immutable

對於不變類型的無用操做:對於不變類型對象 (StringBigDecimal BigInteger) 的操做不會改變對象自己,但操做結果是產生新的對象,因此操做的結果是錯的

如:BigDecimal a=new BigDecimal(10);

a.add(newBigDecimal(5));

正確的寫法:

BigDecimal bd=new BigDecimal(10);

bd = bd.add(new BigDecimal(5));

String Literals Equality

避免用== or != 比較 String

StringBuffer Instantiation With Char

StringBuffer sb = new StringBuffer('c'); 

字符 c 會轉換爲 int 值,做爲 StringBuffer 的初始化大小參數

Servlet reflected cross site scripting vulnerability 

public void doGet(HttpServletRequestrequest,HttpServletResponse response)throws ServletException,IOException{

  String v = request.getParameter("v");

  PrintWriter out = response.getWriter();

  out.print("協議版本號不對,v="+v);

  out.close();

}

這裏字符串v沒有做過濾,直接返回給用戶,有可能操做XSS攻擊

JSP reflected cross site scripting vulnerability

在代碼中在JSP輸出中直接寫入一個HTTP參數,這會形成一個跨站點的腳本漏洞

Call to static DateFormat

private static  SimpleDateFormat dateFormat = newSimpleDateFormat("yyyy-MM-dd"); 

避免使用靜態的DateFormat,DateFormat 是非線程安全的

Call to static Calendar

同上

Don’t use removeAll to clear a collection

清空集合使用clear() 代替removeAll()

Avoid printStackTrace

在代碼中避免使用e.printStackTrace,使用logger代替

System.println

代碼中禁止使用System.println

While For loop If Else Stmts Must use braces

While for 循環If Else 代碼塊必須使用大括號

Dead store to local variable

爲局部變量賦值,但在其後的沒有對她作任何使用。一般,這代表一個錯誤,由於值從未使用過。

Method uses the same code for two branches

此方法使用相同的代碼,以實現兩個有條件的分支。檢查以確保這是否是一個編碼錯誤


 

checkstyle常見提示速查

         Checkstyle常見錯誤和警告提示見下表所示:

錯誤提示

 

錯誤說明

 

缺乏類註釋

行長度超過X個字符(包括空格)

一個方法內的返回數量是X(最大值只能爲3)

最大的if-else嵌套層數爲X(最大隻能爲3)

數組的方括號「[]」的位置不正確(檢查數組類型的定義是String[] args,而不是String args[]

本行包含System.out.println語句

縮進不正確,通常是由於沒有在Eclipse中使用4個空格代替tab鍵引發。

static修飾符沒有按照JLS的建議來排序(eg.寫成public final static...應該改爲public static final)

正則表達式)

 

名稱不符合正則表達式'^[A-Z][A-Z0-9][_A-Z0-9+]$'(即爲大寫字母,數字、下劃線等)

 

通常在靜態變量沒有大寫時提示,包名不是所有消息時提示,類名不是大寫開頭時提示,方法名不是小寫開頭時提示

變量定義順序不正確(例如在類成員變量定義時,將private類型的變量定義在public類型的變量以前)

靜態變量定義順序不正確(例如在構造函數以後定義靜態變量)

成員變量定義順序不正確(例如在構造函數以後定義成員變量)

X是一個魔術數字(012的數字)

if結構必須使用'{}'

由於沒有設置checkstyle配置文件的charsetUTF-8,而類文件使用UTF-8編碼,而且含有中文

{ should be on the previous line

 

{」 應該位於前一行

 

方法前面缺乏javadoc註釋

Exception

 

在註釋中但願有@throws的說明

 

. Is preceeded with whitespace

 

.」 前面不能有空格

 

. Is followed by whitespace

 

.」 後面不能有空格

 

= is not preceeded with whitespace=

 

前面缺乏空格

 

= is not followed with whitespace

 

=」 後面缺乏空格

 

} should be on the same line

 

}」 應該與下條語句位於同一行

 

unused

 

沒有參數「unused」,不需註釋

 

X missing javadoc

 

變量「CA」缺乏javadoc註釋

 

行含有」tab」 字符

Public modifier

 

冗餘的「public modifier

 

final修飾符的順序錯誤

.* form of import

 

格式避免使用「.*

 

從同一個包中Import內容

Unused import-X Import

X類沒有被使用

 

重複Import同一個內容

從非法包中 Import內容

while construct must use {}

 

while」 語句缺乏「{}

 

X must be private and have accessor method

 

變量「X」應該是private的,而且有調用它的方法

 

X must match pattern ^[a-z][a-zA-Z0-9]*$

 

變量「X」不符合命名規則「^[a-z][a-zA-Z0-9]*$

 

( is followed by whitespace

 

(」 後面不能有空格

 

) is proceeded by whitespace

 

)」 前面不能有空格

 

 

 

 PMD

 檢查Java源文件中的潛在問題。

 主要包括:

  -  空try/catch/finally/switch語句塊

 -       未使用的局部變量、參數和private方法

 -       空if/while語句

 -       過於複雜的表達式,如沒必要要的if語句等

 -       複雜類

CheckStyle

 檢查java源文件是否與代碼規範相符

 主要包括

 -       Javadoc註釋

 -       命名規範

 -       Headers

 -       Imports

 -       Size衝突和度量,如過長的方法

 -       Whitespace

-       Modifiers

 -       Blocks

 -       Coding Problems

 -       Class Design

 -       重複代碼

 -       Miscellaneous Checks

 -       Optional Checks

  配套的Bug解釋模式

爲了有針對性的使用這個工具,減小bug的誤報,提升使用效率,咱們選擇了10個左右的bug模式,下面就是對這10個模式的解釋。

這些bug可能會引發程序的性能或邏輯問題.

須要說明的是,findbugs能檢測的bug pattern遠不只於此,甚至能夠定製本身的探測器,所以,這個文檔會不斷擴充,同時,也歡迎你們不斷探索和分享使用實踐.

大的分類主要包括如下幾種:

Bad practice

很差的習慣

Correctness

代碼的正確性

Dodgy

小問題

Malicious code vulnerability

惡意代碼

Internationalization

國際化問題

Performance

性能問題

Security

安全性問題

Multithreaded currectness

線程問題

Experrimental

實驗性問題

 


 

FindBugs常見錯誤描述和解決方法


(一)[DLS_DEAD_LOCAL_STORE]
描述: Dead store to 未使用的局部變量
解決方法:局部變量定義後未使用;實例化對象後又從新對該對象賦值


(二) [ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD] 
描述:Write to static field 經過實例方法更新靜態屬性
常見於常量類,直接經過類名.常量名獲取的方式違背了封裝的原則,findbugs不提倡使用,而若是將常量改爲靜態成員變量,又由於spring不支持靜態注入致使不能實現,解決方法是非靜態的setter調用靜態的setter方法給靜態成員變量賦值。
解決方法:
常量類F:
class F{
public static String a = 「123」;
}
常量a改成靜態成員變量,經過F.getA()獲取,且因爲spring不支持靜態注入,改成:
class F{
    private static String a;
    public static Integer getA() {
return a;
}
public void setA(String a) {
setAValue(a);
}
public static void setAValue(String a) {
F.a = a;
}
}


(三) [BX_UNBOXING_IMMEDIATELY_REBOXED]
描述: Boxed value is unboxed and then immediately reboxed  裝箱的值被拆箱,而後馬上從新裝箱了
常見的是三目運算時,同時存在基本類型和包裝類型。
解決方法:
Integer a = null;
//...
a = (a == null)?0:a;
此問題在於a不爲null時,會被拆箱,賦值時再裝箱。這是自動裝箱拆箱的特性,只要運算中有不一樣類型,當涉及到類型轉換時,編譯器就會向下轉型,再進行運算。修改方法,統一類型:
Integer a = null;
//...
a = (a == null)?Integer.valueOf(0):a;


(四) [SE_BAD_FIELD] 
描述: Non-transient non-serializable instance field in serializable class在可序列化的類中存在不能序列化或者不能暫存的數據
解決方法:
方法1:序列化該對象
方法2:當採用struts2框架開發,不可避免的此問題會大量出現,由於ActionSupport實現了序列化接口,action繼承了此類,而service沒序列化,因此在action中引用service對象時提示此錯誤,最簡單的解決方法是將service對象聲明成transient,即service不須要序列化
方法3(未驗證):To avoid Java serialization you need to implement writeObject() and readObject() method in your Class and need to throw NotSerializableException from those method.(action中實現這兩個方法?)
private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
    throw new java.io.NotSerializableException( getClass().getName() );
}
private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
    throw new java.io.NotSerializableException( getClass().getName() );
}


(五) [NP_LOAD_OF_KNOWN_NULL_VALUE] 
描述: Load of known null value加載已知是null的值
解決方法:已知方法參數爲null是,直接傳遞null而不是參數名


(六) [REC_CATCH_EXCEPTION]
描述: Exception is caught when Exception is not thrown 過泛地捕獲異常或捕獲異常後未作任何處理
解決方法:異常分類捕獲(至少要打印出此異常對象)


(七) [NP_NULL_PARAM_DEREF]
描述: Null passed for nonnull parameter  把空值傳給了非空的參數
解決方法:增長非空判斷


(八) [NP_IMMEDIATE_DEREFERENCE_OF_READLINE]
描述: Immediate dereference of the result of readLine() 當即引用了readLine()的結果
解決方法:判斷readLine的結果是否爲空


(九) [EI_EXPOSE_REP] 惡意代碼漏洞
描述:may expose internal representation by returning  getter方法返回引用類型
eclipse自動生成的引用類型(Object、數組、Date等)的getter、setter方法會獲得或經過對可變對象的引用操做而暴露代碼內部實現,解決方法不少,只要返回的或賦值的對象不是原引用對象便可。
解決方法:
以Date類型爲例:
public Date getHappenTime() {
if(happenTime != null){
return (Date) happenTime.clone();
}
    return null;
}


(十) [ EI_EXPOSE_REP2] 惡意代碼漏洞
描述:may expose internal representation by storing an externally mutable object into  setter方法返回引用類型
eclipse自動生成的引用類型(Object、數組、Date等)的getter、setter方法會獲得或經過對可變對象的引用操做而暴露代碼內部實現,解決方法不少,只要返回的或賦值的對象不是原引用對象便可。
解決方法:
以Date類型爲例:
public void setHappenTime(Date happenTime) {
if(happenTime != null){
this.happenTime = (Date) happenTime.clone();
}else{
this.happenTime = null;
} }

相關文章
相關標籤/搜索