wordpress用戶關(guān)系360搜索關(guān)鍵詞優(yōu)化軟件
解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界
盡管 Object
類提供了 toString
方法的默認實現(xiàn),但它返回的字符串通常不是類的使用者想要看到的。默認返回的字符串格式是類名加上“@”符號和哈希碼的十六進制表示,例如 PhoneNumber@163b91
。然而,toString
方法的合同要求返回一個簡潔且信息豐富的字符串表示,以便用戶閱讀。顯然,與“707-867-5309”相比,“PhoneNumber@163b91”并不具備太多的可讀性和信息量。因此,建議重寫 toString
方法。
雖然重寫 toString
不如重寫 equals
和 hashCode
那樣重要(如【條目10】和【條目11】所述),但提供一個良好的 toString
實現(xiàn)能讓你的類更加易用,且有助于調(diào)試。當對象被傳遞給 println
、printf
、字符串連接操作符或斷言語句時,toString
會自動調(diào)用。即使你不主動調(diào)用 toString
,其他人可能會。例如,某個組件在記錄錯誤消息時可能會包含對象的字符串表示。如果你沒有重寫 toString
,這些消息幾乎是無用的。
為什么要重寫 toString
如果你為 PhoneNumber
提供了一個好的 toString
方法,那么生成有用的診斷消息會變得非常簡單:
System.out.println("Failed to connect to " + phoneNumber);
不論你是否重寫 toString
,程序員通常都會以這種方式生成診斷消息,但只有當你重寫了 toString
,這些消息才真正有用。toString
的好處不僅體現(xiàn)在類的實例本身,也會反映在包含這些實例的對象上,特別是集合。比如,當你打印一個 Map
時,哪一個更可讀:{Jenny=PhoneNumber@163b91}
還是 {Jenny=707-867-5309}
?
toString
方法應(yīng)盡可能返回對象中的所有有趣信息。對于較大的對象或不適合字符串表示的對象,可以返回摘要信息,例如 Manhattan residential phone directory (1487536 listings)
或 Thread[main,5,main]
。理想情況下,字符串應(yīng)該是自解釋的。
格式化和文檔化
實現(xiàn) toString
時,一個重要的決定是是否要在文檔中指定返回值的格式。對于像電話號碼這樣的值類,建議指定格式,因為這可以為對象提供一種標準且明確的表示,可以用于輸入、輸出以及持久化數(shù)據(jù)(如 CSV 文件)。如果你指定了格式,最好提供匹配的靜態(tài)工廠方法或構(gòu)造函數(shù),以便程序員能夠在對象和字符串表示之間輕松轉(zhuǎn)換。許多 Java 平臺庫中的值類(如 BigInteger
、BigDecimal
和大多數(shù)包裝類)都采用了這種方法。
指定 toString
格式的缺點是,一旦你指定了格式,就必須長期堅持使用,特別是當你的類被廣泛使用時。如果將來修改了表示格式,可能會導(dǎo)致程序崩潰或數(shù)據(jù)損壞。因此,如果你不指定格式,就保留了將來改進格式的靈活性。
無論是否指定格式,都應(yīng)該明確記錄你的意圖。如果指定格式,要精確說明。例如,下面是與【條目11】中的 PhoneNumber
類相匹配的 toString
方法文檔:
/*** 返回該電話號碼的字符串表示。* 字符串由十二個字符組成,格式為“XXX-YYY-ZZZZ”,* 其中 XXX 是區(qū)號,YYY 是前綴,ZZZZ 是號碼。* * 如果這三個部分中的任意一部分不夠長,會用前導(dǎo)零填充。* 例如,如果號碼值是 123,字符串表示的最后四個字符將是“0123”。*/
@Override
public String toString() {return String.format("%03d-%03d-%04d", areaCode, prefix, lineNum);
}
如果你選擇不指定格式,則文檔注釋可能會類似如下:
/*** 返回該藥水的簡短描述。表示的具體細節(jié)未指定,并且可能會變化,* 但通常的格式可能如下:** "[Potion #9: type=love, smell=turpentine, look=india ink]"*/
@Override
public String toString() {// 自定義實現(xiàn)
}
這種文檔確保了使用者在解析字符串表示時不能抱怨格式變化引發(fā)的問題。
提供訪問器
無論是否指定 toString
格式,都應(yīng)提供程序化訪問對象信息的途徑。以 PhoneNumber
類為例,應(yīng)該提供獲取區(qū)號、前綴和號碼的訪問器。如果沒有這些訪問器,程序員不得不解析字符串來獲取這些信息,這不僅降低了性能,還可能導(dǎo)致錯誤的系統(tǒng)。如果沒有訪問器,即使你聲明字符串格式是可變的,它實際上仍然會成為一個事實上的 API。
特殊情況
不必在靜態(tài)工具類(【條目4】)或大多數(shù) enum
類型中編寫 toString
方法,因為 Java 已經(jīng)為 enum
提供了一個很好的默認實現(xiàn)。不過,在抽象類中,如果子類共享相同的字符串表示形式,則應(yīng)該編寫 toString
方法。例如,許多集合實現(xiàn)繼承了抽象集合類的 toString
實現(xiàn)。
此外,Google 的開源 AutoValue
工具可以自動生成 toString
方法,絕大多數(shù) IDE 也提供了自動生成 toString
的功能。這些自動生成的方法對于了解類的字段內(nèi)容非常有用,但并不適合表示類的特定含義。例如,電話號碼類應(yīng)該有一個標準的字符串表示,而藥水類則可以接受自動生成的 toString
方法。不過,自動生成的 toString
方法仍然比繼承自 Object
的默認實現(xiàn)好得多,后者幾乎無法提供任何有用信息。
總結(jié)
除非超類已經(jīng)重寫了 toString
,否則在你編寫的每個實例類中都應(yīng)重寫 toString
。這會讓你的類更易用,并有助于調(diào)試。toString
方法應(yīng)返回對象的簡潔、有用的描述,并且格式美觀。