简体   繁体   English

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

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

I see a lot of legacy code like this: 我看到很多这样的遗留代码:

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

I don't see any reason for the intern(), as in the Javadoc one can read: "All literal strings and string-valued constant expressions are interned." 我没有看到intern()的任何原因,因为在Javadoc中可以读取:“所有文字字符串和字符串值常量表达式都被实现。” Is there some intent of this, maybe in past revisions of the language? 是否有一些这样的意图,也许是在过去的语言修订版中?

This is a technique to ensure that CONSTANT is not actually a constant. 这是一种确保CONSTANT实际上不是常量的技术。

When the Java compiler sees a reference to a final static primitive or String, it inserts the actual value of that constant into the class that uses it. 当Java编译器看到对最终静态原语或String的引用时,它会将该常量的实际值插入到使用它的类中。 If you then change the constant value in the defining class but don't recompile the using class, it will continue to use the old value. 如果然后更改定义类中的常量值但不重新编译using类,它将继续使用旧值。

By calling intern() on the "constant" string, it is no longer considered a static constant by the compiler, so the using class will actually access the defining class' member on each use. 通过在“常量”字符串上调用intern(),编译器不再将其视为静态常量,因此using类实际上将在每次使用时访问定义类的成员。


JLS citations: JLS引文:

The use of intern() with the constant string literal is a waste of time as the literal will already be interned as specified by section 3.10.5. 使用带有常量字符串文字的intern()是浪费时间,因为文字已经按照3.10.5节的规定进行了实习 String Literals of The Java® Language Specification . Java®语言规范的 字符串文字

Quoting from Java SE 8 Edition: 引用Java SE 8 Edition:

Moreover, a string literal always refers to the same instance of class String. 此外,字符串文字始终引用类String的相同实例。 This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern. 这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被“实例化”以便使用String.intern方法共享唯一实例。

I guess the coder didn't appreciate this fact. 我想编码器并不欣赏这个事实。

Edit: 编辑:

As kdgregory has pointed out there is an impact on how this constant may be inlined. 正如kdgregory所指出的那样,这个常数如何被内联会产生影响。

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

A while ago I intern()ed all of the Strings coming from class files (for a classfile parser). 前一段时间我实习()编辑了来自类文件的所有字符串(用于类文件解析器)。 Intern()ing made the program use less memory (won't in this case as others have pointed out) but it did slow the program down significantly (I think it took 4 seconds to parse all of rt.jar and that change put it over 8 seconds). Intern()使得程序使用更少的内存(在这种情况下不像其他人指出的那样)但是它确实使程序显着减慢(我认为解析所有rt.jar需要4秒钟,而且这个改变就把它放了超过8秒)。 Looking into it at the time (was JDK 1.4 I think) the intern() code is pretty ugly and slower that in probably needs to be. 当时正在研究它(我认为是JDK 1.4)intern()代码非常难看且速度慢,可能需要。

If I were to consider calling intern() in my code I would first profile it without intern() and then profile it with intern() for both memory and speed and see which one is "worse" for the change. 如果我考虑在我的代码中调用intern(),我将首先在没有intern()的情况下对其进行分析,然后使用intern()对内存和速度进行概要分析,并查看哪一个对于更改更“糟糕”。

I have used intern() for "locking". 我使用intern()进行“锁定”。 For instance, let's say I have a "repository" of "trade records". 例如,假设我有一个“交易记录”的“存储库”。 While I edit and update a trade I want to lock the trade; 当我编辑和更新交易时,我想锁定交易; I might instead lock on the tradeId.intern() so that I don't have to worry about clones of a trade floating around. 我可能会锁定tradeId.intern(),这样我就不用担心交易的克隆了。 I am not sure if everybody likes this usage. 我不确定是否每个人都喜欢这种用法。

This assumes that the id field is unlikely to accidentally collide with the id field of another domain object - a tradeId doesn't happen to collide with account_number for instance, where one might also be doing 这假设id字段不太可能意外地与另一个域对象的id字段冲突 - 例如,tradeId碰巧不会与account_number冲突,其中一个人也可能正在做

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

see example 例子

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

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