1. 介紹
為什麼在 Java 中字串比較很重要?
在 Java 程式設計中,字串被廣泛使用於各種情境。檢查使用者名稱、驗證表單輸入、以及驗證 API 回應,都需要進行字串比較。
此時,「如何正確比較字串」 是初學者常見的卡關點。尤其是未能了解 == 運算子與 equals() 方法之差異,會導致 意外的錯誤。
不了解 “==” 與 “equals” 差異的危險
請參考以下程式碼:
String a = "apple";
String b = new String("apple");
System.out.println(a == b); // result: false
System.out.println(a.equals(b)); // result: true
許多人對此輸出感到驚訝。即使字串內容相同,== 仍回傳 false,而 equals() 回傳 true。 這是因為 Java 將字串視為參考型別,== 會比較參考位址。
了解正確的字串比較方式直接影響程式的可靠性與可讀性。若能正確掌握,便能在錯誤發生前就加以防止。
本文將學到什麼
本文將從基礎到實務應用說明 Java 的字串比較,並解答以下問題:
==與equals()有何差異?- 如何在比較字串時忽略大小寫?
- 如何進行字典序(字母順序)比較?
- 在與 null 比較時,如何避免例外?
透過實務範例,你將對 正確的字串比較實踐 有扎實的認識。
2. Java 中字串的基礎
字串是參考型別
在 Java 中,String 類型不是原始型別(如 int 或 boolean),而是 參考型別。String 變數不會直接儲存字元本身,而是 指向儲存在堆積記憶體中的物件的參考。
例如:
String a = "hello";
String b = "hello";
a 與 b 可能指向相同的 "hello" 字面值,這是因為 Java 的 字串常值化(string interning) 機制。
字面值字串與 new String() 的差異
Java 會透過重複使用相同的參考來最佳化字面值字串:
String s1 = "apple";
String s2 = "apple";
System.out.println(s1 == s2); // true (same literal, interned)
然而,使用 new 總是會建立一個新物件:
String s3 = new String("apple");
System.out.println(s1 == s3); // false (different references)
System.out.println(s1.equals(s3)); // true (same content)
因此,== 檢查的是 參考,而 equals() 檢查的是 內容。
字串是不可變的
另一個重要特性是 String 為 不可變(immutable)。字串一旦建立後就無法更改。
String original = "hello";
original = original + " world";
這會產生一個新的 String 物件,而不是修改原本的字串。
3. 比較字串的方法
使用 == 比較參考
== 會比較物件的參考:
String a = "Java";
String b = new String("Java");
System.out.println(a == b); // false
它 不應 用於內容比較。
使用 equals() 比較內容
equals() 是比較字串內容的正確方式:
String a = "Java";
String b = new String("Java");
System.out.println(a.equals(b)); // true
避免 NullPointerException
String input = null;
System.out.println(input.equals("test")); // Exception!
使用常數在前的寫法:
System.out.println("test".equals(input)); // false, safe
使用 equalsIgnoreCase() 忽略大小寫
String a = "Hello";
String b = "hello";
System.out.println(a.equalsIgnoreCase(b)); // true
使用 compareTo() 進行字典序比較
- 0 → 相等
- 負值 → 呼叫者排在前面
- 正值 → 呼叫者排在後面
String a = "apple"; String b = "banana"; System.out.println(a.compareTo(b)); // negative
4. 實務範例
使用者登入檢查
String inputUsername = "Naohiro";
String registeredUsername = "naohiro";
if (registeredUsername.equalsIgnoreCase(inputUsername)) {
System.out.println("Login successful");
} else {
System.out.println("Username does not match");
}
密碼比較應始終使用 equals(),因為需要區分大小寫。 
表單輸入驗證
String selectedOption = request.getParameter("plan");
if ("premium".equals(selectedOption)) {
System.out.println("Premium plan selected.");
} else {
System.out.println("Other plan selected.");
}
使用多個字串檢查的分支邏輯
String cmd = args[0];
if ("start".equals(cmd)) {
startApp();
} else if ("stop".equals(cmd)) {
stopApp();
} else {
System.out.println("Invalid command");
}
switch (cmd) {
case "start":
startApp();
break;
case "stop":
stopApp();
break;
default:
System.out.println("Unknown command");
}
安全處理 null
String keyword = null;
if ("search".equals(keyword)) {
System.out.println("Searching...");
}
5. 效能與最佳化
字串比較的成本
equals() 與 compareTo() 會在內部比較字元。對於長字串或重複比較,可能會影響效能。
使用 String.intern() 以提升效能
String a = new String("hello").intern();
String b = "hello";
System.out.println(a == b); // true
僅在必要時使用,以避免記憶體壓力。
equalsIgnoreCase() 的效能影響
String input = userInput.toLowerCase();
if ("admin".equals(input)) {
// fast comparison
}
使用 StringBuilder / StringBuffer
StringBuilder sb = new StringBuilder();
sb.append("user_");
sb.append("123");
String result = sb.toString();
if (result.equals("user_123")) {
// comparison
}
使用快取或映射減少比較
Map<String, Runnable> commandMap = new HashMap<>();
commandMap.put("start", () -> startApp());
commandMap.put("stop", () -> stopApp());
Runnable action = commandMap.get(inputCommand);
if (action != null) {
action.run();
}
6. 常見問題
Q1. == 與 equals() 有何差異?
A.
==比較參考equals()比較字串內容
Q2. 為何當變數為 null 時 equals() 會拋出錯誤?
String input = null;
input.equals("test"); // Exception
使用常數在前的比較方式:
"test".equals(input);
Q3. 如何在比較字串時忽略大小寫?
stringA.equalsIgnoreCase(stringB);
Q4. 如何比較字母順序?
a.compareTo(b);
7. 結論
正確選擇比較方法很重要
因為 String 是參考型別,錯誤的比較常會導致意外行為。了解 == 與 equals() 的差異是必備知識。
檢查清單
==:比較參考equals():比較內容equalsIgnoreCase():忽略大小寫compareTo():字典順序"constant".equals(variable):null 安全- 針對大量比較使用
intern()或快取
實用且必備的知識
字串比較出現在登入驗證、表單驗證、資料庫操作、分支邏輯以及日常許多任務中。掌握正確的技巧有助於撰寫更安全、更可靠的程式碼。 在使用 Java 處理字串時,請將本指南作為參考。

