整理Effective Java書中Item 12: Always override toString心得筆記

主旨

Object 提供了一個 toString() 方法的預設實作,但它返回的字串通常不是使用者希望看到的。預設返回的字串由類名及其哈希碼的十六進制表示組成,例如:PhoneNumber@163b91。這樣的格式雖然簡潔,但與 707-867-5309 比起來,並不具備足夠的資訊。

toString() 方法的通用契約指出,返回的字串應該是「簡潔且具資訊量的,且容易閱讀的格式」,但 PhoneNumber@163b91 這樣的字串雖簡潔,卻缺乏實際意義。契約還強調:「建議所有子類別都應該覆寫此方法」,這確實是個好建議!

劃重點

為什麼覆寫 toString() 方法很重要?

  • 調試與可讀性toString() 方法在調試時非常有用,當物件被傳遞給 println()printf()、字串連接運算符或 assert,或是由除錯器印出時,toString() 會自動被呼叫。如果沒有覆寫 toString(),生成的診斷訊息可能完全沒有幫助。
  • 提高 HashMap 等集合的可用性:如果你將物件當作 HashMap 的鍵,覆寫 toString() 可以讓你在印出 Map 時看到更有意義的訊息,而不是像 PhoneNumber@163b91 這樣毫無意義的字串。

實際範例:覆寫 toString() 方法

假設你有一個 PhoneNumber 類別,應該為它提供一個有用的字串表示形式:

@Override
public String toString() {
    return String.format("%03d-%03d-%04d", areaCode, prefix, lineNum);
}

實際範例:覆寫 toString() 方法

這樣覆寫 toString() 方法,能夠將 PhoneNumber 物件以 707-867-5309 這樣的格式輸出,比 PhoneNumber@163b91 更具實用性。

實際應用場景

如果你沒有覆寫 toString(),生成的診斷訊息將可能完全沒有意義,特別是在日誌或錯誤訊息中。例如,當你印出一個 Map 時,你更願意看到類似 {Jenny=707-867-5309} 的輸出,而不是 {Jenny=PhoneNumber@163b91}

小結

  • 覆寫 toString() 方法可以大大提升類別的可用性,尤其在調試和生成有用的錯誤訊息時。
  • 當實作 toString() 方法時,應該提供一個簡潔且實用的物件描述,並確保其格式容易被人類閱讀。
  • 避免使用像 PhoneNumber@163b91 這樣的預設表示,因為它不具備足夠的資訊。