`System.out.print(obj)` 內部調用 `String.valueOf(obj)` → `obj.toString()`。**不同類重寫 `toString()` 行為不同**。
// java.lang.Throwable 源碼片段
public String toString() {
String s = getClass().getName(); // 異常類全限定名
String message = getLocalizedMessage(); // 異常詳細信息
return (message != null) ? (s + ": " + message) : s;
}
// 示例
try { int a = 1/0; }
catch (Exception e) {
System.out.println(e);
// 輸出: java.lang.ArithmeticException: / by zero
}
// java.lang.Object 源碼
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 示例
class A {}
A a = new A();
System.out.println(a);
// 輸出: A@15db9742 (類名@哈希碼十六進制)
| 類別 | toString() 目標 | 設計邏輯 |
|---|---|---|
| 異常/錯誤 | **診斷信息** | 開發者最關心「什麼錯」及「哪裡錯」,類名+信息直擊痛點。 |
| 集合/數組/包裝類 | **內容可視化** | `ArrayList` 輸出 `[a, b, c]`,`Integer` 輸出 `123`,便於調試。 |
| 普通業務類 | **標識區分** | 默認提供「類名@哈希碼」唯一標識對象實例,避免內存洩漏風險(不序列化字段)。 |
**所有業務實體類必須重寫 `toString()`**,推薦使用 IDE 自動生成或 Lombok `@ToString`:
@Data // Lombok 包含 @ToString
public class User {
private Long id;
private String name;
private int age;
// 輸出: User(id=1, name=ZhangSan, age=25)
}
// 或手寫 (IntelliJ: Alt+Insert → toString())
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
打印對象本質是調用 `toString()`。**異常類重寫為「類名:信息」**,**默認 `Object.toString()` 為「類名@哈希碼」**。**業務類務必重寫 `toString()` 輸出關鍵字段**,是提升開發調試效率、日志可讀性的零成本高收益習慣。