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

时间:2009-12-02 15:21:28

标签: java string string-interning

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

class A {
    public static final String CONSTANT = "value".intern();
    ...
}

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

4 个答案:

答案 0 :(得分:68)

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

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

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


JLS引用:

答案 1 :(得分:17)

intern()与常量字符串文字一起使用会浪费时间,因为文字已按照3.10.5. String LiteralsThe Java® Language Specification部分的指定进行实习。

引用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

答案 2 :(得分:7)

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

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

答案 3 :(得分:0)

我使用intern()进行“锁定”。例如,假设我有一个“交易记录”的“存储库”。当我编辑和更新交易时,我想锁定交易;我可能会锁定tradeId.intern(),这样我就不用担心交易的克隆了。我不确定是否每个人都喜欢这种用法。

这假设id字段不太可能意外地与另一个域对象的id字段冲突 - 例如,tradeId不会碰到与account_number冲突,其中一个人也可能正在进行

synchronized(account.getAccountNumber().intern()) {...}

请参阅example