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引文:
编译时常量的定义:http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#5313
改变编译时常量的含义(大约在页面的一半):http://docs.oracle.com/javase/specs/jls/se6/html/binaryComp.html#45139
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
前一段时间我实习()编辑了来自类文件的所有字符串(对于类文件解析器).Intern()使得程序使用更少的内存(在这种情况下不像其他人指出的那样)但是它确实使程序显着减慢(我认为解析所有rt.jar需要4秒钟,而且这个改变就把它放了超过8秒).当时正在研究它(我认为是JDK 1.4)intern()代码非常难看且速度慢,可能需要.
如果我考虑在我的代码中调用intern(),我将首先在没有intern()的情况下对其进行分析,然后使用intern()对内存和速度进行概要分析,并查看哪一个对于更改"更糟糕".