当然,除了它们与原语一起使用。我看到的大多数(如果不是全部)实现仅从程序员的角度来看是有用的。
编辑:我知道我应该覆盖默认行为,这就是我提到实现的原因:)。而且我确实得到了在一些需要在 GUI 中使用字符串表示的组件中覆盖它的价值。但是,至少在 JDK 中,我看到许多仅在需要调试对象实例时才使用的实现。
为什么它植根于 Object 类,因为它似乎只对 GUI/调试有用?还有其他我不知道的用途吗?
不,关键是您应该覆盖的默认实现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()
方法可能更常见,例如 .NETDateTime
类。( ToShortDateString()
, ToLongDateString()
, ToLongTimeString()
, ...)
编辑:至于为什么它植根于Object
班级,这仅仅是因为ToString()
is a valid operation for anything。
此外,字符串可能是数据类型或数据使用者之间编组的好方法,因为它(实际上)保证是可解析的并且不需要额外的编码或照顾。
我个人的偏好是 toString()不应该用于调试以外的任何事情。如果要为对象生成字符串,请提供一个单独的方法来清楚地记录您的意图(getName()、getDescription() 等)。永远不要依赖 toString() 的实现。
问题是许多开发人员将 toString() 视为调试级别的字符串,并没有考虑更改它(例如添加或删除新字段时)。哎呀,一些自动 toString() 构建器使用反射从字段生成 toString() 。
多年来,我发现这种偏好对我很有帮助。
当你想要一个对象的字符串表示时,toString() 很有用。当然,这是出于调试目的,但也可以有效地将操作结果输出给用户。
例如,假设您有一个处理复数的 Complex 类。如果您想以3 + 2i之类的格式将它们打印给用户,如果他们定义 toString() 会很方便,因为您不必每次都编写格式并且输出将是一致的。如果您想更改该表示,例如更改为3 + 2j,您只需触摸 Complex 类中的 toString() 方法。
所以 toString() 也不是用于调试目的,而是获得对象的一致字符串表示的好方法。
我只能说,当我更改类的 toString 以显示一些额外的调试信息时,我遇到了代码中断。
有问题的代码是一个 GUI 库,它决定将 toString 的值用作一些内部事物(这是几年前的事了……我忘记了它到底是什么)。最终结果是我不再使用那个库了。
我想说,由于一大群人将 toString 视为用于调试(无论您认为它应该用于什么),因此使用从它返回的值来执行任何程序化操作都是有问题的(比如解析它)或将其显示给用户。
如果您 100% 控制 toString 方法,那么一定要按照您的意愿行事。
所以,回答这个问题,no toString 不仅对调试有用,你可以用它做任何你想做的事情。但是,如果 toString 的变化使您不高兴,请不要感到惊讶。
根据我的经验, toString() 在调试和日志记录之外几乎没有价值。随着时间的推移,您不能依赖它的格式或内容,因此除了人类可读之外,除了最简单的对象(例如原始对象类型)之外,不要依赖它。如果有多个数据成员,预计它们的类型或数量可能会随着时间而改变,toString() 的输出也会随之改变。
我想强烈提出的另一点。不要在 toString() 中调用其他方法。没有什么比在调试器中检查断点上的变量内容更糟糕的了,然后由于 toString() 中的方法调用而执行了更多代码。
我认为重要的是要指出回答提到“toString”的人注意到小写“t”通常是在谈论Java,而回答提到“ToString”的人通常是指C#。当然,这并不适用于所有响应。
在我自己的观察中(我每天都使用),鼓励 C# 中的程序员重写“ToString”以显示有用的文本表示。然而,在 Java 中,我几乎没有看到这一点。事实上,我很少看到这种情况。
-J.P
首先,该toString
方法应该返回对象的人类可读的文本表示。
这个问题在Effective Java中作为第 10 条提出:始终覆盖toString
。
它引用了该方法的Java API 规范Object.toString
:
结果应该是一个简洁但信息丰富的表示,易于人们阅读。
除了调试之外,在将对象添加到 a或 atoString
时,覆盖类的方法可能很有用,默认情况下将使用该方法将对象显示为列表或表格中的文本形式。JList
JTable
toString
例如,在我的例子中,我重写了toString
添加到 a 的对象的方法,JList
以便用户能够通过 GUI 在列表中查看有关项目的信息。
因此,确实存在该toString
方法对调试以外的情况有用的情况。关键是让该toString
方法返回对人们实际有用的信息,而不是默认Object.toString
实现,其中对象的内存位置用于其文本表示。
对...有用
以及任何其他字符串输出。
在将任何对象打印到字符串时,.NET Framework 也会隐式调用 ToString()。
Console.WriteLine("My Object is" + object.ToString());
相当于
Console.WriteLine("My Object is" + object);
因为 ToString() 被隐式调用。
我相信,尽管不确定,它被调试器用于对象的“值”。这可以相当方便,虽然有限。在大多数情况下,编写自己的调试器可视化工具会是一个更好的主意。
在 AS3 上,我必须将 2D 数组转换为 1D 数组。最快(运行速度)和最简单(编码时间)的解决方案是:
var new1DArray:Array = the2DArray.toString().split(",");
感到惊讶,但它实际上也按预期工作并且非常快!
我大量使用 ToString() 来处理日期时间格式。
除了其他人已经说过的,覆盖 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.
它可能不是“有意的”用途,但我已将其用于数据序列化
storeToHardDrive(studentList.ToString());