何时在String文字上使用intern()

Abd*_*dul 38 java string string-interning

我看到很多这样的遗留代码:

class A {
    public static final String CONSTANT = "value".intern();
    ...
}
Run Code Online (Sandbox Code Playgroud)

我没有看到intern()的任何原因,因为在Javadoc中可以读取:"所有文字字符串和字符串值常量表达式都被实现." 是否有一些这样的意图,也许是在过去的语言修订版中?

kdg*_*ory 69

这是一种确保CONSTANT实际上不是常量的技术.

当Java编译器看到对最终静态原语或String的引用时,它会将该常量的实际值插入到使用它的类中.如果然后更改定义类中的常量值但不重新编译using类,它将继续使用旧值.

通过在"常量"字符串上调用intern(),编译器不再将其视为静态常量,因此using类实际上将在每次使用时访问定义类的成员.


JLS引文:

  • 我想人们不应该改变其他类可见的常量值. (2认同)
  • 替代方案 A:对字符串调用 toString()。这可能比 intern() 更快吗?替代方案 B:实用方法: String str(String s){ return s; 该方法应该因其目的而被注释 - 打破编译时间常量,以便读者在看到时明白发生了什么: static Final String ABC = str("xxx"); (2认同)

pjp*_*pjp 17

使用intern()常量字符串文字是浪费时间,因为文字将按3.10.5节的规定进行实习.字符串文字的Java®的语言规范.

引用Java SE 8 Edition:

此外,字符串文字始终引用类String的相同实例.这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被"实例化"以便使用String.intern方法共享唯一实例.

我想编码器并不欣赏这个事实.

编辑:

正如kdgregory所指出的那样,这个常数如何被内联会产生影响.

1 - https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.5

  • JLS讨论了结果,但是不清楚这种折叠是在编译时发生的,还是在运行时编译时折叠和连接 - 然后实习之间是否必须存在可观察到的差异.字节代码检查将回答两个字符串连接的文字是否在类文件中变为一个. (3认同)

Tof*_*eer 7

前一段时间我实习()编辑了来自类文件的所有字符串(对于类文件解析器).Intern()使得程序使用更少的内存(在这种情况下不像其他人指出的那样)但是它确实使程序显着减慢(我认为解析所有rt.jar需要4秒钟,而且这个改变就把它放了超过8秒).当时正在研究它(我认为是JDK 1.4)intern()代码非常难看且速度慢,可能需要.

如果我考虑在我的代码中调用intern(),我将首先在没有intern()的情况下对其进行分析,然后使用intern()对内存和速度进行概要分析,并查看哪一个对于更改"更糟糕".

  • 哇...而准确信息的投票是为了什么?提供的信息有误吗? (3认同)
  • 我不关心投票...只是他们的原因:-) (3认同)