| 方法 | 語法 | 空值處理 | 類型安全 | 適用場景 |
|---|---|---|---|---|
| toString() | obj.toString() | 拋 NullPointerException | 任意對象 (Object 定義) | 確知非空、需業務含義字符串 |
| 強制轉型 | (String) obj | 返回 null | 編譯期通過,運行期風險 (ClassCastException) | 確知對象即為 String/子類 |
| String.valueOf() | String.valueOf(obj) | 返回 "null" 字符串 | 任意對象 (靜態方法) | 可能為空、需安全轉換 |
Object obj = getObject();
System.out.println(obj.toString()); // obj 為 null → NPE
Object,默認實現:getClass().getName() + "@" + Integer.toHexString(hashCode())obj != nullObject obj = new Integer(100);
String s = (String) obj; // 編譯通過!運行拋 ClassCastException
Integer num = new Integer(100);
String s2 = (String) num; // 編譯錯誤:Integer 不兼容 String
Object 可轉任意引用類型)null 可轉為任意引用類型:(String) null 合法,結果為 nullinstanceof 檢查public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
"null" (長度 4)String.valueOf(null) == "null" 為 true,但 String.valueOf(null) == null 為 false!System.out.println(String.valueOf(null)) 輸出 null,與 System.out.println(null) 視覺相同,但語義截然不同// 錯誤
if (String.valueOf(obj) == null) { ... } // 永不執行!valueOf 永不返回 null
// 正確
if (obj == null) { ... }
if (String.valueOf(obj).equals("null")) { ... } // 若真需檢查 "null" 字符串
// 模糊
logger.info("Value: " + String.valueOf(value)); // value=null 記錄 "Value: null"
// 清晰
logger.info("Value: {}", value); // SLF4J 佔位符:null 顯示 "null",但結構化日誌可區分
// 或
logger.info("Value: " + (value == null ? "NULL" : value.toString()));
Map
obj.toString() (領域對象已覆寫)String.valueOf(obj) (日誌、調試、顯示)(String) obj (配合 instanceof 或非空斷言)String.valueOf(map.get(key)) 或模式匹配 (Java 16+)// 模式匹配 instanceof (Java 16+)
if (obj instanceof String s) {
// s 為 String 類型,非空
return s;
}
return String.valueOf(obj); // 其他情況安全轉換
// switch 表達式 (Java 14+)
String result = switch (obj) {
case String s -> s;
case null -> "NULL";
default -> obj.toString();
};
toString() 為領域對象業務表示;String.valueOf() 為通用安全轉換 (返回 "null" 字符串);(String) 為類型斷言 (需配合檢查)。理解「null 引用」vs「\"null\" 字符串」的本質區別,是避免生產 Bug 的關鍵。日誌框架佔位符 ({}) 是現代最佳實踐,避免字符串拼接開銷與語義模糊。