首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 打印對象:為何異常對象輸出信息、普通對象輸出地址?

     編輯:程式設計綜合問答

核心原因

`System.out.print(obj)` 內部調用 `String.valueOf(obj)` → `obj.toString()`。**不同類重寫 `toString()` 行為不同**。

異常類 `Throwable.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
}

普通類 `Object.toString()` 默認實現


// 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()

**所有業務實體類必須重寫 `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()`**:`log.info("user={}", user)` → 輸出重寫後的字符串。
  • **JSON 序列化替代**:`log.info("user={}", JSON.toJSONString(user))` 獲取完整結構,適合複雜對象。
  • **避免在 `toString()` 中觸發懶加載/副作用**:只讀取基本字段,不調用服務/查詢數據庫。

總結

打印對象本質是調用 `toString()`。**異常類重寫為「類名:信息」**,**默認 `Object.toString()` 為「類名@哈希碼」**。**業務類務必重寫 `toString()` 輸出關鍵字段**,是提升開發調試效率、日志可讀性的零成本高收益習慣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved