| 表達式 | 類型 | 內存結構 | 長度 | 含義 |
|---|---|---|---|---|
null | 引用值 | 棧中引用指向 無對象 | N/A | 未指向任何對象 |
"" | String 對象 | 堆/常量池中 長度為0 的字符串對象 | 0 | 存在但內容為空 |
new String() | String 對象 | 堆中 新創建 的長度為0對象 | 0 | 每次調用新建對象 |
棧 (Stack) 堆
+----------+ +------------------+
| str1 ──────────────────→ | "abc" (常量池) |
+----------+ +------------------+
| str2 = null | (無對象) |
+----------+ +------------------+
| str3 = "" ─────────────→ | "" (常量池單例) |
+----------+ +------------------+
| str4 = new String("") → | new String() 對象 |
+----------+ +------------------+
關鍵點:
"" 字面量編譯期進入字符串常量池,全局唯一new String("") 運行期在堆創建新對象,繞過常量池public class StringNullEmptyDemo {
public static void main(String[] args) {
String s1 = new String(); // 堆新對象 ""
String s2 = null; // 無對象
String s3 = ""; // 常量池 ""
System.out.println("s1==s2: " + (s1==s2)); // false (地址不同)
System.out.println("s1.equals(s2): " + s1.equals(s2)); // false (null)
System.out.println("s2==s3: " + (s2==s3)); // false
System.out.println("s3.equals(s2): " + s3.equals(s2)); // false
System.out.println("s1==s3: " + (s1==s3)); // false (堆 vs 常量池)
System.out.println("s1.equals(s3): " + s1.equals(s3)); // true (內容相同)
}
}
== 比較引用地址,equals() 比較字符內容.equals("") 均為 truenew String() 默認值為 "",非 nullif (str == null || str.equals(""))
equals(),有多態查找開銷if (str == null || str.length() == 0)
length() 是 final 方法,直接讀取 value.length 執行極快if (str == null || str.isEmpty())
length() == 0,性能持平寫法二if (str == null || str == "")
"" 或 String.intern() 後的對象才可靠new String()、substring()、網絡/文件讀取的字符串// ❌ 錯誤:先調用 equals 再判 null,若 str 為 null 直接 NPE
if (str.equals("") || str == null) { ... }
// ✅ 正確:短路原理,先判 null
if (str == null || str.equals("")) { ... }
// ✅ 更佳:長度檢查
if (str == null || str.length() == 0) { ... }
public final class StringUtils {
private StringUtils() {}
public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
}
public static boolean isBlank(CharSequence cs) {
int len;
if (cs == null || (len = cs.length()) == 0) return true;
for (int i = 0; i < len; i++) {
if (!Character.isWhitespace(cs.charAt(i))) return false;
}
return true;
}
public static boolean isNotEmpty(CharSequence cs) { return !isEmpty(cs); }
public static boolean isNotBlank(CharSequence cs) { return !isBlank(cs); }
}
| 場景 | 推薦寫法 | 備註 |
|---|---|---|
| 判空(含null) | str == null || str.length() == 0 | 全版本最優 |
| 判空白(含空格/換行) | StringUtils.isBlank(str) | Apache Commons / 自封裝 |
| JDK 11+ | str.isBlank() | 原生支持 Unicode 空白字符 |
| 集合/數組判空 | CollectionUtils.isEmpty(list) | 同理先判 null 再判 size |
記住:先判 null,再檢查長度,是處理字符串判空的鐵律。