【问题标题】:Is toString() only useful for debugging?toString() 仅对调试有用吗?
【发布时间】:2009-02-19 01:56:11
【问题描述】:

当然,它们与原语一起使用。我看到的大多数(如果不是全部)实现仅从程序员的角度有用。


编辑:我知道我应该覆盖默认行为,这就是我提到实现的原因:)。而且我确实得到了在一些需要在 GUI 中使用字符串表示的组件中覆盖它的价值。但是,至少在 JDK 中,我看到 很多 只在需要调试对象实例时才使用的实现。

为什么它植根于 Object 类,因为它似乎只对 GUI/调试有用?还有其他我不知道的用途吗?

【问题讨论】:

  • 针对多种语言的问题必然会根据该语言的公认做法得到不同的结果。

标签: c# java tostring


【解决方案1】:

不,关键是您应该覆盖ToString() 的默认实现以使其有用。 ToString() 是一种将某些东西的值输出回 UI 的好方法。

一个简单的例子是,如果您有一个包含三个字符串(First、Middle、Last)的 Name 类。您可以使用 ToString() 方法为 UI 设置格式:例如“Last, First Middle”。

或存储数学运算的类(值 Left=2、Right=3、Result=6 和运算符 enum=Multiply)。致电ToString() 获取“2 * 3 = 6”。

然而,拥有各种不同的To<qualifier>String() 方法可能更为常见,例如.NET DateTime 类。 (ToShortDateString(), ToLongDateString(), ToLongTimeString(), ...)

编辑:至于为什么它植根于Object 类,仅仅是因为ToString() 是对任何事物的有效操作。

此外,字符串可以成为数据类型或数据使用者之间编组的好方法,因为它(实际上)保证是可解析的,并且不需要额外的编码或照顾。

【讨论】:

  • 非常完整的跟进。我只是在想 toString() 的 GUI 标记的东西被过度使用了。为什么不用implements interface TextualRepresentation 之类的东西?
  • 我同意这对任何事情都是有效的操作,但仅从程序员的角度来看。我的观点是,没有任何合同规定该方法应提供 GUI 友好的字符串或公开实例(字段)的特定内部结构,这仅对程序员有用,恕我直言
  • 通常不利于 UI 目的,因为它不需要用户区域设置。对调试没有影响,对最终用户很重要。
  • 对于 Java,我完全不同意这个答案。对于 C#,我不知道公认的做法是什么。根据该语言的公认做法,将问题定位到多种语言必然会得到不同的结果。
【解决方案2】:

我个人的偏好是,toString() 应该从不用于除调试以外的任何事情。如果您想为一个对象生成一个字符串,请提供一个单独的方法来清楚地记录您的意图(getName()、getDescription() 等)。永远不要依赖 toString() 的实现。

问题在于,许多开发人员将 toString() 视为调试级别的字符串,并没有考虑更改它(例如添加或删除新字段时)。哎呀,一些自动 toString() 构建器使用反射从字段生成 toString()。

多年来,我发现这种偏好对我很有帮助。

【讨论】:

  • 鉴于 String 是编程中最有用的构造,知道程序空间中的每个对象都满足提供自身字符串表示的合同可能非常强大。与任何强大的东西一样,它可以被滥用,但避免它是一种浪费。
  • 但是鉴于合同 a) 对字符串的格式没有任何保证,并且 b) 没有提供从 String 转换回对象的对称 api,我发现它是一个弱合同。我已经调试了许多与假设 toString 不存在的“合同”有关的问题。
  • 我的看法一模一样。我认为 GUI 标签文本表示的东西只是过度使用该方法。
  • @Alex Miller - 完全同意。字符串表示除了应该是人类可读的以外没有任何意义,对于任何复杂的对象,不要指望一种漂亮的格式,只是用于调试。
【解决方案3】:

toString() 在你想要一个对象的字符串表示时很有用。当然,这是出于调试目的,但也可以有效地将操作结果输出给用户。

例如,假设您有一个处理复数的 Complex 类。如果您想以 3 + 2i 之类的格式将它们打印给用户,如果他们定义 toString() 会很方便,因为您不必每次都编写格式并且输出将为持续的。如果您想更改该表示,例如更改为 3 + 2j,您只需触摸 Complex 类中的 toString() 方法。

所以 toString() 也不是用于调试目的,而是获得对象的一致字符串表示的好方法。

【讨论】:

  • 确实如此,但完全不能保证consistent string representation
  • 我得到了一个带有 FooFileSections 的 FooFile 类。要编写文件,我只需为文件本身覆盖 ToString:FooFile.ToString() 以及每个文件部分:FooFileSections.ToString()。然后我通过为 FooFileSections 以正确的顺序调用 ToString 来构建文件内容,然后只是流式传输文本。总体而言可能不是一个好方法,但又快又容易。
  • "输出操作结果给用户"。由于toString() 文本未国际化,因此该文本对用户的总体有用程度值得怀疑。
【解决方案4】:

我只能说,当我更改类的 toString 以显示一些额外的调试信息时,我遇到了代码中断。

有问题的代码是一个 GUI 库,它决定将 toString 的值用作一些内部事物(这是几年前的事了……我忘记了它到底是什么)。最终结果是我不再使用那个库了。

我会说,由于一大群人将 toString 视为用于调试(不管您认为它应该用于什么),因此使用从它返回的值是有问题的做任何程序化的事情(比如解析它)或将它显示给用户。

如果您能 100% 控制 toString 方法,那么请务必按照您的意愿行事。

所以,回答这个问题,no toString 不仅对调试有用,你可以用它做任何你想做的事情。但是,如果 toString 的变化让您不高兴,请不要感到惊讶。

【讨论】:

  • 我只能说,除了调试之外,这是一个非常非常容易泄漏的抽象 :)
【解决方案5】:

根据我的经验,toString() 在调试和日志记录之外几乎没有什么价值。随着时间的推移,您不能依赖它的格式或内容,因此除了人类可读之外,除了最简单的对象(例如原始对象类型)之外,不要依赖它。如果有多个数据成员,预计它们的类型或数量可能会随着时间而改变,toString() 的输出也会随之改变。

我想强调的另一点。不要在 toString() 中调用其他方法。没有什么比在调试器中检查断点上的变量内容更糟糕的了,然后由于 toString() 中的方法调用而执行了更多代码。

【讨论】:

    【解决方案6】:

    我认为重要的是要指出回答提到“toString”的人注意到小写“t”通常是在谈论Java,而回答提到“ToString”的人通常是指C#。当然,这并不适用于所有响应。

    在我自己的观察中(我每天都使用),鼓励 C# 中的程序员重写“ToString”以显示有用的文本表示。然而,在 Java 中,我几乎没有看到这一点。事实上,我很少看到这种情况。

    -JP

    【讨论】:

      【解决方案7】:

      首先,toString 方法应该返回对象的人类可读的文本表示。

      此问题在Effective Java 中作为第 10 项:始终覆盖 toString

      它为Object.toString 方法引用了Java API Specification

      结果应该简洁但 信息表示是 易于阅读。

      除了调试之外,在将对象添加到JListJTable 时,覆盖类的toString 方法可能很有用,默认情况下将使用toString 方法将对象显示为文本在列表或表格中形成。

      例如,在我的例子中,我重写了添加到 JList 的对象的 toString 方法,以便用户能够通过 GUI 在列表中查看有关项目的信息。

      因此,确实存在toString 方法对调试以外的情况有用的情况。关键是让toString 方法返回对人们实际有用的信息,而不是默认的Object.toString 实现,其中对象的内存位置用于其文本表示。

      【讨论】:

        【解决方案8】:

        有用
        1. Gui(使用 PropertyGrid 时的复杂属性,表单标题文本)
        2. DataBinding(这就是它的工作方式)

        以及任何其他字符串输出。

        【讨论】:

          【解决方案9】:

          在将任何对象打印到字符串时,.NET Framework 也会隐式调用 ToString()。

          Console.WriteLine("My Object is" + object.ToString());
          

          等价于

          Console.WriteLine("My Object is" + object);
          

          因为 ToString() 被隐式调用。

          我相信,虽然我不确定,它被调试器用于对象的“值”。这可以相当方便,虽然有限。在大多数情况下,编写自己的调试器可视化器会是一个更好的主意。

          【讨论】:

          • 调试器可能会为某些对象调用 ToString(),但不是全部,如 List 所示,其中调试器输出比 ToString() 的输出更有用。
          【解决方案10】:

          在 AS3 上,我必须将二维数组转换为一维数组。最快(运行速度)和最简单(编码时间)的解决方案是:

          var new1DArray:Array = the2DArray.toString().split(",");
          

          感到惊讶,但它实际上也按预期工作并且速度非常快!

          【讨论】:

            【解决方案11】:

            我大量使用 ToString() 来处理日期时间格式。

            http://hunterconcepts.com/content/tools/formats/

            【讨论】:

              【解决方案12】:

              除了其他人已经说过的,覆盖 ToString() 在使用调用它的控件时也很有用。例如,一个组合框:

              myComboBox.Items.Add(new MyClass());
              // now, whatever ToString() returns is shown in the
              // ComboBox, but you can get the object back by through
              // the SlectedItem property.
              

              【讨论】:

                【解决方案13】:

                这可能不是“有意的”用途,但我已将其用于数据序列化

                storeToHardDrive(studentList.ToString());
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-10-23
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-09-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-05-10
                  相关资源
                  最近更新 更多