跨Java虚拟机实现的Java toString表示?

时间:2013-01-09 06:47:57

标签: java jvm

对于大多数核心库和Java类,所有Java实现中的'toString'表示都是标准的。或者这不是在Java规范中指定的。

例如,如果我这样做,新的HashMap()/ toString是OpenJDK的输出,预计与IBM jrockit相同。

它们应该兼容吗?如果您将代码从一个JVM移植到另一个JVM并且期望字符串表示相同,则可能会出现问题。

4 个答案:

答案 0 :(得分:4)

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(),请注意您可能需要修复非便携式单元测试作为移植工作的一部分。

答案 1 :(得分:2)

好问题,我会说这是依赖于实现的。没有正式的规范。虽然像http://www.amazon.com/The-Java-Class-Libraries-Volume/dp/0201310023这样的书清楚地表明图书馆会做什么,但并不一定说“应该做”。

因此,实现者可以自由选择并记录toString()显示的内容,但不保证显示在其他JVM实现中是相同的。

要解决您的问题,确保toString()实施的唯一方法是在派生类中使用@Override public String toString()方法(是的,您必须派生所需的每个类toString() for)并明确指定其输出。

答案 2 :(得分:0)

根本不要期望[toString()方法]的字符串输出是相同的。未指定方法的内容和格式(查看关联的javaDoc)。

甚至不能保证,来自同一供应商的不同版本的实现是相同的。因此,永远不要将实例与toString()的结果进行比较,或者将这些结果用作数据库或标识符中的关键字。它们只是 实例的文本表示。没什么。

答案 3 :(得分:0)

JLS说:

  

1.4。与预定义类和接口的关系

     

如上所述,此规范通常是指Java的类   SE平台API。特别是,有些课程有特殊之处   与Java编程语言的关系。例子包括   类,如Object,Class,ClassLoader,String,Thread和   java.lang.reflect包中的类和接口等。   该规范约束了这些类的行为   接口,但不提供完整的规范。   读者可以参考Java SE平台API文档。

所以......不,没有规范需要你描述的内容。