簡體   English   中英

什么時候不希望在Java中實現toString()?

[英]When is it desired to not implement toString() in Java?

我項目的首席開發人員已經將項目的toString()實現稱為“pure cruft”,並希望將它們從代碼庫中刪除。

我已經說過這樣做意味着任何希望顯示對象的客戶都必須編寫自己的代碼來將對象轉換為字符串,但是回答“是的,他們會”。

具體來說,這個系統中的對象是矩形,圓形等圖形元素,當前表示是顯示x,y,比例,邊界等...

那么,人群在哪里撒謊?

什么時候你應該什么時候不應該實現toString?

他們有什么害處? 為什么要刪除它們? 我發現toString()在發出調試語句時非常有用。

就個人而言,我總是錯誤地認為有一個可行的toString()方法。 寫作工作很少。

刪除寫得很好(甚至中途寫得不好)的toString()方法是純粹的瘋狂,IMO。 是的,我經常懶得寫這些(因為這些對象通常不會最終使用它們),但它們非常方便。

我真的想不出想要擺脫這些的好理由。

我總是確保我的類實現了toString。

它提供了一種在我調試時調試類的當前狀態的簡單方法,當我記錄錯誤時,我可以將它包含在我的日志消息中。

我會保留toString()實現。 它們在調試時非常有用,它們可以為圖形組件提供良好的替代文本。

我認為相反,toString()應該明智地重寫。 默認的toString()實現是非常無法提供的,基本上沒用。 一個好的toString()實現可以為開發人員提供一個非常有用的對象內容視圖。 你可能不必把所有東西放在那里,但至少是重要的東西。 我認為你的首席開發人員應該實際編碼和添加功能,而不是擔心“殘酷”。

我只會為更復雜的對象實現它,其中客戶端代碼不關心對象狀態的細粒度細節,而是關心一些更易於理解的感知消息,總結正在發生的事情,狀態明智。 。

對於其他一切,比如JavaBeans,如果需要進行低級調試,我希望客戶端代碼將我的對象拋出到ToStringBuilder方法或類似方法中

ToStringBuilder.reflectionToString(myObject);

或者客戶端代碼應該只調用標准屬性getter並記錄他們喜歡的方式...

通常, toString()是好東西。 特別是,它對調試非常有用

實現toString()並非沒有成本風險 與所有代碼一樣, toString()實現必須與其余代碼一起維護 這意味着保持toString()與類字段同步。 例如,當添加或刪除字段時,應該適當地更新toString() (您應該已經為hashCode()equals()等方法執行此操作。

實現toString()也會帶來風險 例如,假設系統中的兩個類引用了另一個類的實例(雙向鏈接),那么調用toString()可能會因為無限遞歸而導致堆棧溢出,因為每個類中的toString()實現class調用另一個類的toString()實現。

如果您的系統有大量不同步的toString()方法,或導致堆棧溢出等錯誤的方法,那么您的同事可能有一個合理的觀點。 即使在這種情況下,我也只是將錯誤的toString()方法注釋掉,並將它們留在代碼中。 每個toString()方法都可以取消注釋,並在將來根據需要單獨更新。

我總是為我的所有POJODTO和/或任何持有持久數據的對象自動生成 toString()方法。 對於私人內部物業,良好的伐木實踐應該可以解決問題

永遠記得用[Omitted]替換toString方法密碼和其他的sesitive信息 (或類似的頂級secrete性質)

好吧,他確實扼殺了一件事。

我不能說toString()太有用了。 對於演示文稿,您將需要其他工具。

但toString()對於調試非常有用,因為您可以看到集合的內容。

我不明白為什么刪除它已經寫好了

我認為答案取決於你的toString()方法有多復雜,需要維護多少工作,以及它們的使用頻率。 假設您經常使用toString()進行日志記錄和調試,刪除這些方法沒有多大意義。 但是如果很少使用它們並且每次代碼中的某些更改都需要大量的工作來維護,那么可能有一個有效的參數來擺脫所有或部分toString()方法。

您提到了有關需要顯示這些對象的客戶端的信息。 從這里我猜你的代碼是或包含其他開發人員將使用的某種庫或API。 在這種情況下,我強烈建議您維護有用的toString()實現。 即使您沒有進行大量的日志記錄和調試,您的客戶也可能會非常欣賞有用的toString()方法,而這些方法不需要自己編寫和維護。

+1 Mike C

除了調試的有用性之外,toString()是一個非常有用的工具,可以理解類作者對實例的看法。

FWIW,如果toString的輸出與你期望看到的(禮貌的規范文檔)不同,你會立刻知道一些嚴重的錯誤。

就個人而言,當我要在JList,JTable或其他使用toString()的結構中使用OR時,我實現它們,或者在我調試時(是的,eclipse有調試格式化程序,但toString()更容易)。

也許你可以反擊許多JDK類有toString()。 他們也應該被刪除嗎? ;)

我會說你應該實現toString,如果這是一個預期的用例或要求,將對象顯示為字符串表示(在日志中,在控制台上,或某種顯示樹)。

否則,我同意開發人員 - 每次更改內容時,toString都會中斷。 您可能必須小心空值等。

但是,很多時候,它實際上用於調試或日志記錄,所以它們根本不應該被排除在外並不明顯。

我同意jsight,如果它們已經寫好並且寫得很好,請至少留下它們,直到它們妨礙它們(例如你實際上在一個類中添加一個字段)。

出於調試目的,沒有人可以擊敗toString 它在調試器和簡單的調試打印中都很實用。 確保它顯示了equalshashCode方法所基於的所有字段,如果你也覆蓋它們!

為了顯示給最終用戶,我不會使用toString 為此,我認為最好編寫另一種方法,進行正確的格式化,如果需要,可以使用i18n。

這很有道理,因為你總是遇到toStrings顯示太少或太多信息的問題。

您的團隊可能有意義使用Jakarta Commons Lang中的ToStringBuilder:

System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));

它反映了對象,並打印出公共字段。

http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/builder/ToStringBuilder.html

我已經說過這樣做意味着任何希望顯示對象的客戶都必須編寫自己的代碼來將對象轉換為字符串,但是回答“是的,他們會”。

這不是一個可以孤立回答的問題......你應該問客戶(或寫作他們的人)他們對這個想法的看法。 如果我使用Java庫並依賴其toString()重載進行調試,那么如果庫的開發人員決定清除它們,我會非常惱火。

公平地說,開發人員在這里,但不是任何意義上的首席開發人員。

原始問題不一定是關於toString(),而是關於第二個方法paramString:“使用它的所有字符串連接和空值檢查,paramString是一個bug磁體。”

請參閱http://code.google.com/p/piccolo2d/issues/detail?id=99

我肯定會保留toString()實現,特別是出於調試目的。 作為一個主要的C ++開發人員,我希望在這方面C ++中的東西和Java一樣簡單(運算符重載可能會很麻煩)。

如果現有的toString()實現存在問題,開發人員應該解決問題。 說當前的實現都是“純粹的愚蠢”並且刪除它們正在積極地造成傷害,除非現有的toString()方法寫得不常見

強烈建議開發人員不要刪除任何有效的toString()方法。

總是實現:)如上所述,它對於調試是非常寶貴的。

它適用於調試目的。 但是如果要將給定對象作為字符串顯示給最終用戶,則不應該使用toString()實現,而是為此提供自定義方法。

所以關於

我已經說過這樣做意味着任何希望顯示對象的客戶都必須編寫自己的代碼來將對象轉換為字符串,但是回答“是的,他們會”。

我同意你的團隊領導。 如果要向任何客戶端顯示對象,請使用自定義實現。 如果要將其用於調試目的,請使用toString()。

盡管toString()方法對於調試值類非常有用,但可以認為它們對實體類沒有用

我認為,考慮到這個問題已經有近10年的歷史了,我會更加現代化。

toString顯然對調試很有幫助 - 你需要看看這里證明的所有其他答案 - 但是調試信息不​​是業務邏輯

在每個類中都有一個toString方法是視覺混亂,它模糊了類的有用行為。 我們還需要記住維護它 - 每次我們更改類字段時手動或通過從IDE重新生成方法。

那么,如果不完全刪除這個方法,我們可以做些什么來解決這些問題呢? 答案是自動生成它 Project Lombok的@ToString注釋可以在編譯時為您自動生成一個toString方法,其中包括您選擇的任何字段組合。

基本樣本用法:

@ToString
public class Foo {
    private int i = 0;
}

在編譯時,這將等同於以下內容:

public class Foo {
    private int i = 0;

    public String toString() {
        return "Foo(i=" + this.i + ")";
    }
}

我們從一個toString()方法中拋出了一個ConcurrentModificationException,所以偶爾會有一個缺點。 當然,沒有讓它同步是我們自己的錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM