5

com.sun.org.apache.xerces.internal.impl.XMLScanner的源代码第 183 行和第 186 行

183    protected final static String fVersionSymbol = "version".intern();

186    protected final static String fEncodingSymbol = "encoding".intern();

为什么“版本”“编码”是通过使用 intern() 显式实习的,而它们是字符串文字并且会自动实习?

4

2 回答 2

6

在 Apache Xerces SVN 存储库中追踪到修订版 318617的更改(这是最初开发此 XML 解析器的项目,正如包名所暗示的那样)。

提交消息的相关部分是:

试图改进符号表的使用。每次重置解析器时,都会将许多预定义的字符串添加到符号表中。对于小型文档,这将是一笔巨大的成本。现在,由于我们为符号表中的字符串调用 String#intern,因此对那些预定义的符号使用 String#intern 就足够了。这只需要执行一次。

正如您所指出的,对于.intern()符合要求的 JVM 实现,这应该不是必需的(并且应该没有明显的影响)。

我的猜测是

  • 要么作者不知道字符串文字将始终被保留的事实
  • 或者这是一个有意识的决定,以防止行为不端的 JVM 实现

但是,在第二种情况下,我希望在评论或评论消息中对此进行一些说明。

该调用的一个副作用.intern()是初始化程序不再是常量表达式,并且字段不会被引用它们的其他类内联。这将确保XMLScanner加载类并读取其字段。但是,我认为这与这里无关。

于 2012-11-02T14:24:15.287 回答
4

我不认为有任何充分的理由,因为您确定的原因:文字总是自动实习,String定义:

所有文字字符串和字符串值的常量表达式都是实习的。字符串文字在Java™ 语言规范的第3.10.5节中定义。

于 2012-11-02T14:14:45.947 回答