Java程式碼走查審查規範總結
阿新 • • 發佈:2018-12-04
按照我的經驗,一般來說,從命名,註釋,宣告,語句/功能分佈/規模,可靠性(總則/變數和語句/函式),可靠性(函式),程式碼警告,可讀性,圈複雜度,SQL規範性和優化效能等如下方面稽核:
分類 | 重要性 | 檢查項 | 具體要求 |
命名 | |||
重要 | 命名規則是否與所採用的規範保持一致? | 成員變數,方法引數等需要使用首字母小寫,其餘單詞首字母大寫的命名方式,禁止使用下劃線(_)數字等方式命名 不要出現區域性變數,成員變數大寫字母開頭等問題 | |
一般 | 是否遵循了最小長度最多資訊原則? | 各種命名儘可能短,表意準確,除2代替‘to’,4代替‘for’外,不建議使用數字在命名中 | |
重要 | has/can/is字首的函式是否返回布林型? | 成員變數,方法引數,區域性變數等為布林型時,如果出現has/can/is開頭,則將這些詞去掉 | |
重要 | 類名是否存在重名問題? | 自己實現的類儘量不要和別人的類重名,儘管不在同一個包下,特別是子類和父類重名的情況 | |
註釋 | |||
重要 | 註釋是否較清晰且必要? | 方法JAVADOC註釋中需要說明各引數、返回值及異常說明,引數說明需按照引數名稱及用意對應標註 | |
重要 | 複雜的分支流程是否已經被註釋? | ||
一般 | 距離較遠的}是否已經被註釋? | ||
重要 | 函式是否已經有文件註釋?(功能、輸入、返回及其他可選) | 檔案,類(含介面,列舉等),成員變數,方法前需要有JAVADOC的註釋 | |
一般 | 特殊用法是否被註釋? | ||
宣告、空白、縮排 | |||
一般 | 每行是否只聲明瞭一個變數?(特別是那些可能出錯的型別) | ||
重要 | 變數是否已經在定義的同時初始化? | ||
重要 | 類屬性是否都執行了初始化? | ||
一般 | 程式碼段落是否被合適地以空行分隔? | ||
一般 | 是否合理地使用了空格使程式更清晰? | 基本程式碼格式中的空格符不可缺少,這些空格出現在?,:,+,-,*,/,=,==,>,<,>=,<=,!=,及各種括號附近 | |
提示 | 程式碼行長度是否在要求之內? | 每行不得超過120個字元 | |
重要 | controller,service, dao 中不要宣告有狀態的變數。 | 此變數不能被修改。如果要進行修改,必須通過鎖進行控制。 | |
一般 | 折行是否恰當? | ||
一般 | 集合是否被定義為泛型型別? | 定義集合時,建議定義其泛型型別,減少型別轉換和警告錯誤 | |
語句/功能分佈/規模 | |||
一般 | 包含複合語句的{}是否成對出現並符合規範? | ||
重要 | 是否給單個的迴圈、條件語句也加了{}? | if,else,else if,while,for,case等程式碼塊必須用{}包圍 | |
一般 | 單個變數是否只做單個用途? | ||
重要 | 單行是否只有單個功能?(不要使用;進行多行合併) | ||
重要 | 單個函式是否執行了單個功能並與其命名相符? | ||
一般 | 操作符++和— —操作符的應用是否符合規範? | ||
規模 | |||
重要 | 單個函式不超過規定行數? | ||
重要 | 縮排層數是否不超過規定? | ||
可靠性(總則/變數和語句) | |||
重要 | 是否已經消除了所有警告? | 開發工具的警告 | |
重要 | 常數變數是否宣告為final? | ||
重要 | 物件使用前是否進行了檢查? | ||
重要 | 成員變數,區域性變數是否在使用前被賦值? | 物件初始化為null的物件被呼叫前必須被重新賦值,如果賦值語句在try塊中,呼叫操作必須在try塊中 | |
一般 | 區域性物件變數使用後是否被複位為NULL? | 特別是 陣列 集合 Map | |
重要 | 對陣列的訪問是否是安全的?(合法的index取值為[0, MAX_SIZE-1])。 | ||
重要 | 是否確認沒有同名變數區域性重複定義問題? | 嚴禁區域性變數名稱和類或物件成員變數同名 | |
一般 | 程式中是否只使用了簡單的表示式? | ||
重要 | 是否已經用()使操作符優先順序明確化? | ||
重要 | 所有判斷是否都使用了(常量==變數 或者 常量.equals(變數))的形式? | 常量放在比較符前可以有效降低比較符寫成賦值語句 ,減少空指標異常 | |
重要 | 是否每個if-else if-else語句都有最後一個else以確保處理了全集? | ||
重要 | 是否每個switch-case語句都有最後一個default以確保處理了全集? | ||
一般 | for迴圈是否都使用了包含下限不包含上限的形式?(k=0; k<MAX) | ||
重要 | XML標記書寫是否完整,字串的拼寫是否正確? | ||
重要 | 對於流操作程式碼的異常捕獲是否有finally操作以關閉流物件? | 關閉前需要判斷 流物件是否為空 | |
提示 | 退出程式碼段時是否對臨時物件做了釋放處理? | ||
重要 | 對浮點數值的相等判斷是否是恰當的? | 嚴禁使用==直接判斷浮點數值 。提供通用方法 | |
重要 | 是否物件比較都使用了equals? | 物件(包括包裝類)比較必須使用equals,而不是使用==或!=操作 | |
重要 | 使用equals進行比較時是否確保比較的兩個物件型別一致? | equals方法比較的物件在物件型別確定的前提下,建議是同一型別的,例如Integer和""使用equals是不提倡的 | |
一般 | 操作Map或Properties結構物件,用於傳值時是否將Key定義為常量? | Session,Request等物件的setAttribute,getAttribute方法的key建議使用常量,不得手工輸入字串 | |
重要 | 是否在型別轉換前確保了型別的相容? | 除非明確保證物件型別 | |
重要 | 包裝類做簡單預算前是否保證非空? 建議都使用包裝類。 | 包裝類進行操作前,建議進行非空(null != xx)判斷,防止發生空指標異常 | |
重要 | 物件屬性在使用前是否確保被準確賦值? | 只讀屬性(只提供get方法的成員變數)除非特意返回固定值,否則必須提供set方法或在其他方法呼叫時將其賦值 | |
重要 | 方法呼叫前是否有非空判斷? | 對引數的非空判斷必須出現在方法呼叫之前,否則說明前面可能導致空指標或者後者判斷是沒有必要的,非空判斷,預設由呼叫者提供 | |
重要 | 非執行緒安全的物件是否被正確保證執行緒安全? | DateFormat例項的format方法呼叫不是執行緒安全,類似的情況不適合使用static定義,建議使用ThreadLocal方式實現,參看UnifiedCodeGenerator | |
一般 | 相同用意的成員變數是否使用了相同的命名? | 不同實體Entity、VO、BO之間表示同一含義的成員變數,建議使用相同的名稱,儘量不要出現,有的地方用username,有的地方用userName這樣的情況 | |
可靠性(函式) | |||
重要 | 入口物件是否都被進行了判斷不為空? | ||
重要 | 入口資料的合法範圍是否都被進行了判斷? | ||
重要 | 是否對有異常丟擲的方法都執行了try...catch保護? | ||
重要 | 是否函式的所有分支都有返回值? | ||
重要 | int的返回值是否合理?(負值為失敗,非負值成功) | ||
一般 | 對於反覆進行了int返回值判斷是否定義了函式來處理? | ||
一般 | 關鍵程式碼是否做了捕獲異常處理? | ||
一般 | 字典表定義是否用列舉,或者有一個統一的定義? | ||
重要 | 是否對方法返回值物件做了null檢查,該返回值定義時是否被初始化? | ||
重要 | 是否對同步物件的遍歷訪問做了程式碼同步? | ||
重要 | 是否確認在對Map物件使用迭代遍歷過程中沒有做增減元素操作? | Map遍歷時執行增減元素操作將丟擲ConcurrentModificationException,對集合物件遍歷時建議都不要進行增減元素操作。 | |
重要 | 執行緒處理函式迴圈內部是否有異常捕獲處理,防止執行緒丟擲異常而退出? | ||
重要 | 原子操作程式碼異常中斷,使用的相關外部變數是否恢復先前狀態? | ||
重要 | 函式對錯誤的處理是恰當的? | ||
重要 | 異常捕獲後是否進行了日誌記錄或異常繼續丟擲? | 異常捕獲後如果無法處理需要繼續丟擲,如果可以處理,建議將異常日誌進行記錄 | |
重要 | 是否構造方法中不呼叫當前物件的構造方法 | 嚴禁在構造方法中new一個當前物件 | |
可維護性 | |||
重要 | 實現程式碼中是否消除了直接常數?(用於計數起點的簡單常數例外) | ||
重要 | 是否消除了導致結構模糊的連續賦值?(如a= (b=d+c )) | ||
重要 | 是否正確使用了日誌記錄? | ||
一般 | 是否有冗餘判斷語句?(如:if (b) return true; else return false;) | “if (b) return true; else return false;”==》“return b;”;禁止使用類似“if/while(表示式 == true)或if/while(表示式 == false)”的判斷 | |
重要 | 是否把方法中的重複程式碼抽象成私有函式? | ||
程式碼警告 | |||
一般 | 是否清除了多餘匯入的包或類? | ||
重要 | 是否清除了只定義未使用的區域性變數? | 嚴禁區域性變數被定義或者初始化而未被使用,這種情況需要刪除該區域性變數 | |
一般 | 是否將魔鬼數字修改為常量使用? | 不允許直接使用除-2,-1,0,1,2,3,4,5,6,7,8,9,10外的數字,除此外的數字需要定義常量使用 | |
提示 | 常量定義是否為static final格式? | 常量定義格式為public/protected//private static final Type TYPE,static和final順序要保持一致 | |
提示 | 實現序列化的物件是否定義了serialVersionUID? | 建議實現Serializable的類需要增加“private static final long serialVersionUID = 1L;” | |
可讀性 | |||
一般 | 是否用if else結構替換了三元運算子? | 表示式複雜情況下 不要使用(flag?exp1:exp2)語句,該語句需要修改為if else結構 | |
一般 | 程式碼註釋率是否結餘30%~60%之間? | 程式碼註釋率應落在30%~60%之間 | |
效能 | |||
重要 | 日誌記錄的Log,Logger物件是否定義為常量? | 用於記錄日誌的Log,Logger物件在類中定義必須是static final的,建議定義為private的,因為這類物件初始化比較耗時,不利系統執行 | |
日誌 | |||
重要 | 列印資訊是否都用日誌管理? | 程式碼中建議不要使用System.out.println列印資訊,只有在系統啟動或系統即將退出時使用,其餘部分全部用日誌記錄 | |
圈複雜度 | |||
重要 | 單個類行數是否不大於500行? | 單個類建議行數小於500行,最多不超過1000行 | |
重要 | 方法引數個數是否在7個以內? | 方法引數個數建議不大於5個,最多不超過7個 | |
重要 | 單個方法函式是否不大於30行? | 單個方法建議函式不大於30行,做多不超過60行 | |
重要 | 單方法中try/for/while/switch/if最深深度是否不大於5? | 單方法中try/for/while/switch/if最深深度不允許大於5 | |
重要 | 方法呼叫最深深度是否不大於15? | 方法內部+內部呼叫累計深度不允許大於15 | |
SQL空格 | |||
一般 | 連線符or、in、and、以及=、<=、>=等前後加上一個空格。 | ||
一般 | 逗號之後必須接一個空格。 | ||
一般 | 關鍵字、保留字和左括號之間必須有一個空格。 | ||
SQL註釋 | |||
重要 | 對較為複雜的SQL語句加上註釋,說明演算法、功能。註釋風格:註釋單獨成行、放在語句前面。 | ||
重要 | 對重要的計算應說明其功能。 | SQL中儘量少涉及業務邏輯 | |
一般 | 可採用單行/多行註釋。(-- 或 /* */方式)。 | ||
SQL優化效能建議 | |||
1 書寫SQL語句優化細則 | |||
重要 | 1) 儘量避免相同語句由於書寫格式的不同,而導致多次語法分析。 | ||
重要 | 2) 多表連線時,使用表的別名來引用列。 | 建議最多5個連線 | |
重要 | 3) 不要在任何程式碼中使用 SELECT *。 | ||
重要 | 4) where條件中儘量減少使用常量比較,改用引數變數。 | ||
重要 | 5) 儘量少用巢狀查詢。如必須,請用not exist代替not in子句。 | ||
重要 | 6) 用多表連線代替EXISTS子句。 | ||
重要 | 7) 使用UNION ALL提高效能 。 | ||
重要 | 8) in、or子句常會使用工作表,使索引失效;如果不產生大量重複值,可以考慮把子句拆開;拆開的子句中應該包含索引。 | ||
2 排序注意事項 | |||
重要 | 1) 大量的排序操作影響系統性能,所以儘量減少orderby和group by排序操作。如必須使用排序操作,請遵循如下規則: | ||
重要 | a. 排序儘量建立在有索引的列上。 | ||
重要 | b. 如結果集不需唯一,使用union all代替union。 | ||
3 選用索引注意事項 | |||
重要 | 1) 對於複合索引,SQL語句必須使用主索引列。 | ||
重要 | 2) 索引中,儘量避免使用NULL。 | ||
重要 | 3) 對於索引的比較,儘量避免使用NOT=(!=)。 | ||
重要 | 4) 查詢列和排序列與索引列次序保持一致。 | ||
4 其他經驗性規則 | |||
重要 | 1) 任何對列的操作都將導致表掃描,它包括資料庫函式、計算表示式等等,查詢時要儘可能將操作移至等號右邊。 |
微信公眾號: