繁体   English   中英

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

[英]When to use intern() on String literals

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

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

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

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

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

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


JLS引文:

使用带有常量字符串文字的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

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

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

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

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

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

例子

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM