首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 程式設計偏執式技巧 10 選:防禦性編碼實戰精選

     編輯:Java 相關知識

前言

「偏執式程式設計」不是強迫症,而是在不可靠的環境中 (不穩定的 API、惡意輸入、並發競爭、未來變更) 以**最小成本預防最大風險**的思維。以下 10 招源自實戰慘痛教訓。

1. 字串比較:字面值在前防 NPE


// Bad: variable 可能為 null
if (variable.equals("literal")) { ... }

// Good: "literal" 永不為 null
if ("literal".equals(variable)) { ... }

2. 不信任早期 JDK API 回傳值


// File.list() 可能回傳 null (非目錄時)
File dir = new File(path);
if (dir.isDirectory()) {
    String[] files = dir.list();
    if (files != null) { // 雙重防護
        for (String f : files) { ... }
    }
}

3. 索引檢查:不用 -1 用 >= 0


// Bad: 假設 -1 是唯一失敗值
if (str.indexOf(ch) != -1) { ... }

// Good: 語意明確,若未來 API 回傳 -2 也不會誤判
if (str.indexOf(ch) >= 0) { ... }

4. 防止意外賦值:常數在左


// 易寫錯成 =
if (variable = 5) { ... } // 編譯通過 (boolean 語境除外),執行時邏輯錯

// 編譯錯誤:無法指派給常數
if (5 = variable) { ... }

// 現代語言 (JS/TS) 使用 ===
if (5 === variable) { ... }

5. 空值與長度雙重檢查


// Bad: array 可能為 null
if (array.length > 0) { ... }

// Good
if (array != null && array.length > 0) { ... }

// Java 8+ Optional 風格
Optional.ofNullable(array).filter(a -> a.length > 0).ifPresent(a -> { ... });

6. 方法預設 final:禁止意外覆寫


// Bad: 開放覆寫風險
public void process() { ... }

// Good: 明確設計為可覆寫時才移除 final
public final void process() { ... }

7. 變數與參數預設 final


// Bad: 參數可被修改,區域變數可被重新指派
void handle(String msg) {
    String result = "init";
    result = msg = "oops"; // 意外修改參數與區域變數
}

// Good: 編譯期保護
final void handle(final String msg) {
    final String result = "init";
    // result = msg = "oops"; // 編譯錯誤
}

8. 重載陷阱:小心泛型擦除與隱式轉型


// 危險:呼叫端 (Object) list 會匹配錯誤重載
void bad(T value) { bad(Collections.singletonList(value)); }
void bad(List values) { ... }

// 安全:單一進入點 + instanceof 分派
final  void good(final T value) {
    if (value instanceof List) good((List) value);
    else good(Collections.singletonList(value));
}
final  void good(final List values) { ... }

9. switch 必須有 default 拋出例外


// Bad: 新增 enum 值時靜默忽略
switch (status) {
    case NEW: handleNew(); break;
    case DONE: handleDone(); break;
}

// Good: 編譯期/執行期即時發現遺漏
switch (status) {
    case NEW: handleNew(); break;
    case DONE: handleDone(); break;
    default: throw new IllegalStateException("未處理狀態: " + status);
}

10. switch 每個 case 用大括號建立作用域


// Bad: 變數跨 case 洩漏,編譯錯誤
switch (type) {
    case A: int x = 1; break;
    case B: int x = 2; break; // 錯誤:x 已宣告
}

// Good: 獨立作用域
switch (type) {
    case A: { final int x = 1; break; }
    case B: { final int x = 2; break; }
    default: throw new IllegalStateException();
}

總結

這 10 招偏執技巧的核心精神:**假設環境惡劣、假設自己會犯錯、假設需求會變更**。在編譯期、靜態分析、執行期早期攔截錯誤,成本遠低於生產環境修復。內化為編碼肌肉記憶,是資深工程師的分水嶺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved