对于大多数核心库和 Java 类,是所有 Java 实现中的“toString”表示标准。或者这没有在 Java 规范中指定。
例如,如果我这样做,new HashMap()/toString 是 OpenJDK 的输出,预计与 IBM jrockit 相同。
它们应该兼容吗?如果您将代码从一个 JVM 移植到另一个 JVM 并期望字符串表示相同,这可能是一个问题。
方法的输出toString()
(除了少数例外)是未指定的,因此理论上可能会因 Java 的一种实现而异。
然而,大多数商业Java 实现都有派生自 Sun / Oracle 类库的某些版本的类库,无论是 OpenJDK 代码库还是更早的代码库。鉴于 Sun / Oracle 对故意进行可能破坏客户代码的更改持谨慎态度,我希望各自的toString()
方法在很大程度上是兼容的。
但也有一些值得注意的例外;例如基于 GNU Classpath 库、Apache Harvest 库和... Android 的 java 实现。请注意,这些实现没有通过 Java 合规性测试(因为 Oracle 拒绝以可接受的条款许可 TDK !!)所以严格来说它们不能称为 Java(tm)。
最重要的是,在升级 JVM 版本时,对未记录 toString()
格式的依赖可能会导致移植问题或问题。但实际上,出现问题的可能性主要取决于您从什么移植到什么。如果您坚持使用使用 Oracle / Sun 派生类库的 JVM,那么出现问题的可能性很小。
那么你应该怎么做呢?
最极端的立场是避免使用toString
方法(隐式或显式),除非指定了输出格式。但我认为这太过分了。(而且可能很难执行这项政策......)
更现实的立场是避免toString
在精确的输出格式很重要的情况下使用方法。换句话说:
不要toString()
在对象序列化方案中使用……除非指定了格式。
如果您toString()
在单元测试中使用,请注意作为移植工作的一部分,您可能需要修复不可移植的单元测试。
好问题,我会说这取决于实施。没有正式的规范存在。虽然像http://www.amazon.com/The-Java-Class-Libraries-Volume/dp/0201310023这样的书籍清楚地确定了图书馆将做什么,但不一定说“应该做”。
因此,实现者可以自由选择和记录toString()
显示的内容,但不保证显示在其他 JVM 实现中是相同的。
为了解决您的问题,确保toString()
实现的唯一方法是@Override
public String toString()
在派生类中使用方法(是的,您必须派生您想要toString()
的每个类)并明确指定其输出。
只是不要期望 [toString() 方法的] 字符串输出是相同的。未指定方法的内容和格式(查看相关的 javaDoc)。
甚至不能保证来自同一供应商的不同版本的实现是相同的。因此,永远不要通过结果来比较实例,toString()
或者将这些结果用作数据库中的键或一般的标识符。它们只是实例的文本表示。而已。
JLS说:
1.4. 与预定义类和接口的关系
如上所述,本规范通常引用 Java SE 平台 API 的类。特别是,某些类与 Java 编程语言有着特殊的关系。示例包括 Object、Class、ClassLoader、String、Thread 等类,以及 java.lang.reflect 包中的类和接口等。本规范限制了此类类和接口的行为,但没有为它们提供完整的规范。读者可参考 Java SE 平台 API 文档。
所以......不,没有规范需要您描述的内容。