\1. 【強制】在一個 switch
塊內(nèi),每個 case
要么通過 continue
/break
/return
等來終止,要么注釋說明程序?qū)⒗^續(xù)執(zhí)行到哪一個 case
為止;在一個 switch
塊內(nèi),都必須包含一個 default
語句并且放在最后,即使它什么代碼也沒有。
break
是退出 switch
語句塊,而 return
是退出方法體。
\2. 【強制】當 switch
括號內(nèi)的變量類型為 String
并且此變量為外部參數(shù)時,必須先進行 null
判斷。
public class SwitchString {
public static void main(String[] args) {
method(null);
}
public static void method(String param) {
switch (param) {
// 肯定不是進入這里
case "sth":
System.out.println("it's sth");
break;
// 也不是進入這里
case "null":
System.out.println("it's null");
break;
// 也不是進入這里
default:
System.out.println("default");
}
}
}
\3. 【強制】在 if
/else
/for
/while
/do
語句中必須使用大括號。
if (condition) statements;
\4. 【強制】三目運算符 condition? 表達式 1 : 表達式 2 中,高度注意表達式 1 和 2 在類型對齊時,可能拋出因自動拆箱導致的 NPE 異常。
Integer a = 1;
Integer b = 2;
Integer c = null;
Boolean flag = false;
// a*b 的結(jié)果是 int 類型,那么 c 會強制拆箱成 int 類型,拋出 NPE 異常
Integer result=(flag? a*b : c);
\5. 【強制】在高并發(fā)場景中,避免使用”等于”判斷作為中斷或退出的條件。
\6. 【推薦】當某個方法的代碼總行數(shù)超過 10 行時,return
/ throw
等中斷邏輯的右大括號后均需要加一個空行。
\7. 【推薦】表達異常的分支時,少用 if-else
方式,這種方式可以改寫成:
if (condition) {
...
return obj;
}
// 接著寫 else 的業(yè)務(wù)邏輯代碼;
if()...else if()...else...
方式表達邏輯,避免后續(xù)代碼維護困難,請勿超過 3 層。if-else
的邏輯判斷代碼可以使用衛(wèi)語句、策略模式、狀態(tài)模式等來實現(xiàn),其中衛(wèi)語句示例如下:
public void findBoyfriend (Man man) {
if (man.isUgly()) {
System.out.println("本姑娘是外貌協(xié)會的資深會員");
return;
}
if (man.isPoor()) {
System.out.println("貧賤夫妻百事哀");
return;
}
if (man.isBadTemper()) {
System.out.println("銀河有多遠,你就給我滾多遠");
return;
}
System.out.println("可以先交往一段時間看看");
}
\8. 【推薦】除常用方法(如 getXxx
/isXxx
)等外,不要在條件判斷中執(zhí)行其它復雜的語句,將復雜邏輯判斷的結(jié)果賦值給一個有意義的布爾變量名,以提高可讀性。
if
語句內(nèi)的邏輯表達式相當復雜,與、或、取反混合運算,甚至各種方法縱深調(diào)用,理解成本非常高。如果賦值一個非常好理解的布爾變量名字,則是件令人爽心悅目的事情。// 偽代碼如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
...
}
public final void acquire ( long arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
selfInterrupt();
}
}
\9. 【推薦】不要在其它表達式(尤其是條件表達式)中,插入賦值語句。
說明:賦值點類似于人體的穴位,對于代碼的理解至關(guān)重要,所以賦值語句需要清晰地單獨成為一行。
public Lock getLock(boolean fair) {
// 算術(shù)表達式中出現(xiàn)賦值操作,容易忽略 count 值已經(jīng)被改變
threshold = (count = Integer.MAX_VALUE) - 1;
// 條件表達式中出現(xiàn)賦值操作,容易誤認為是 sync==fair
return (sync = fair) ? new FairSync() : new NonfairSync();
}
10.【推薦】循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理,如定義對象、變量、獲取數(shù)據(jù)庫連接,進行不必要的 try-catch
操作(這個try-catch
是否可以移至循環(huán)體外)。
11.【推薦】避免采用取反邏輯運算符。
if (x < 628)
來表達 x 小于 628。if (!(x >= 628))
來表達 x 小于 628。12.【推薦】公開接口需要進行入?yún)⒈Wo,尤其是批量操作的接口。
13.【參考】下列情形,需要進行參數(shù)校驗:
1) 調(diào)用頻次低的方法。
2) 執(zhí)行時間開銷很大的方法。此情形中,參數(shù)校驗時間幾乎可以忽略不計,但如果因為參數(shù)錯誤導致 中間執(zhí)行回退,或者錯誤,那得不償失。
3) 需要極高穩(wěn)定性和可用性的方法。
4) 對外提供的開放接口,不管是 RPC/API/HTTP 接口。
5) 敏感權(quán)限入口。
14.【參考】下列情形,不需要進行參數(shù)校驗:
1) 極有可能被循環(huán)調(diào)用的方法。但在方法說明里必須注明外部參數(shù)檢查。
2) 底層調(diào)用頻度比較高的方法。畢竟是像純凈水過濾的最后一道,參數(shù)錯誤不太可能到底層才會暴露問題。一般 DAO 層與 Service 層都在同一個應(yīng)用中,部署在同一臺服務(wù)器中,所以 DAO 的參數(shù)校驗,可以省略。
3) 被聲明成 private 只會被自己代碼所調(diào)用的方法,如果能夠確定調(diào)用方法的代碼傳入?yún)?shù)已經(jīng)做過檢查或者肯定不會有問題,此時可以不校驗參數(shù)。
更多建議: