Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why constant strings use intern()?

Tags:

java

string

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.

like image 475
rook Avatar asked Jan 21 '14 13:01

rook


2 Answers

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.

like image 132
Duncan Jones Avatar answered Oct 12 '22 23:10

Duncan Jones


To prevent compile time inlining

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.

How does that work?

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

like image 30
Narendra Pathai Avatar answered Oct 12 '22 22:10

Narendra Pathai