判斷字串「非 null 且非空」是 Java 業務代碼最高頻操作之一。本文對比四種寫法的字節碼與實測效能,給出生產環境推薦標準。
| 編號 | 寫法 | 說明 | 字節碼關鍵指令 |
|---|---|---|---|
| 1 | str == null || "".equals(str) | 經典雙重檢查,常數 "" 呼叫 equals | ldc "" + invokevirtual equals |
| 2 | str == null || str.length() == 0 | 直接檢查長度為 0 | invokevirtual length + ifne |
| 3 | str == null || str.isEmpty() | JDK 6+ 專用語意方法 | invokevirtual isEmpty (內部即 length() == 0) |
| 4 | str == null || str == "" | 引用比較,依賴字串常數池,**極不推薦** | if_acmpeq (僅對字面常數有效) |
// 測試程式碼結構
for (int i = 0; i < 10000; i++)
for (int j = 0; j < 10000; j++)
if (判斷條件) { /* empty */ }
結果 (ms):
JudgeString1 ("".equals) : 625
JudgeString2 (length==0) : 125
JudgeString3 (isEmpty) : 234
JudgeString4 (== "") : 109 ← 僅因 JIT 優化常數池引用比較,**實務不可靠**
invokevirtual + 整數比較,JIT 易內聯優化。length()==0),但語意更清晰,JDK 6+ 標準。new String("") == "" 為 false,僅字面常數才為 true,**絕不可用於運行時字串**。// 1. 標準寫法 (JDK 6+)
if (str != null && !str.isEmpty()) { ... }
// 2. 工具類封裝 (推薦 Apache Commons Lang / Spring StringUtils)
if (StringUtils.isNotBlank(str)) { ... } // 同時去除空白字元
// 3. Java 11+ 字串新方法
if (str != null && !str.isBlank()) { ... } // isBlank: 全空白也視為空
// ❌ 錯誤:先呼叫 equals 可能拋 NPE
if (str.equals("") || str == null) { ... }
// ✅ 正確:短路求值,先檢 null
if (str == null || str.isEmpty()) { ... }
// ❌ 錯誤:== 比較內容
if (str == "") { ... }
// ✅ 正確:長度或 isEmpty
if (str != null && str.length() == 0) { ... }
首選 str != null && str.isEmpty() (JDK 6+) 或 str != null && str.length() == 0 (全版本)。引入工具類時優先 StringUtils.isNotBlank。嚴禁使用 == "" 或 != ""。