I'm aware about string pool in JVM and difference between literals and string objects. I know that literals are automatically interned, but what is the purpose of this line then:
public static final String PARAMETER = "value".intern();
On my question I always find a ton of text which explains me the same with emphasis on the difference between literals and objects and mention that literals already interned. Therefore, I'd like to know about underlyings of using that tricky line with intern()
over literal.
The main benefit of that type of code is to prevent compile-time constants from being inlined.
For instance, suppose you have a constant in one class and you have many other classes refer to that constant. Normally if you change the constant value, you'd need to recompile all the classes involved. Using intern()
on the field will prevent inlining of the constant and means it would be sufficient to recompile just your constant class. In theory this approach would have inferior performance, although I have no idea how significant that might be.
This SO question covers the same topic and is a useful read.
The only use case I can think of is to prevent it from being considered as compile time constant, so that it prevents inlining.
Now one reason can be that someone can change the value using Reflection, which will only work if the string is declared like that.
Also it allows you to change the class file containing constant as told by @Duncan in his answer. That is a good reason too.
When you declare String
as public static final String CONST = "abc";
, then it is a compile time constant and will be inlined in the class using that constant.
class A{
private void foo(){
String newString = CONST + someDynamicValue;
}
}
After compiling this, if you decompile the class you will find
class A{
private void foo(){
String newString = "abc" + someDynamicString;
}
}
But when you declare it with .intern()
or any other method, then it cannot be considered as compile time constant and every time the value will be fetched from the class. Java does this to be efficient.
Example from @Marko's comment:
the SWT library uses a similar trick to stop from inlining int constants, and the only reason is to be consistent with respect to upgrading the SWT library
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With