繁体   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