Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is string interning done at compile time in Java? [duplicate]

I am really confused with how string interning works in Java. When I write:

String a = "ABC";
String b = "ABC";

if (a==b)
    System.out.println("Equal");

Does the compiler store the string literal "ABC" into the string constant pool at compile time?

That sounds illogical, because I thought the string constant pool was created by the JVM at runtime, and I don't see how that is possible if it is done at compile time since the Java compiler does not even invoke the JVM.

If it is not done at compile time and it is done at runtime then why does the following return false (taken from this answer)?

// But .substring() is invoked at runtime, generating distinct objects
"test" == "!test".substring(1) // --> false

If it is done at runtime then why can't the JVM figure out that they are the same string?

I am really confused as to how string interning works in Java and where exactly the Java string pool is stored.

like image 960
Kramer786 Avatar asked Apr 26 '15 14:04

Kramer786


People also ask

Does Java automatically intern strings?

intern() in Java. All compile-time constant strings in Java are automatically interned using this method. String interning is supported by some modern object-oriented programming languages, including Java, Python, PHP (since 5.4), Lua,Julia and .

How do string interns work?

intern() The method intern() creates an exact copy of a String object in the heap memory and stores it in the String constant pool. Note that, if another String with the same contents exists in the String constant pool, then a new object won't be created and the new reference will point to the other String.

Can you explain how strings are interned in Java?

String Interning is a method of storing only one copy of each distinct String Value, which must be immutable. By applying String. intern() on a couple of strings will ensure that all strings having the same contents share the same memory.

Where is interned string stored?

Intern strings are stored in a string pool in the JVM memory. JVM Memory has the following regions: Heap region (i.e. Young & Old generation)


1 Answers

The compiler puts the literal strings in the class file (and only unique ones, it consolidates all equivalent literals); the JVM loads those strings into the string pool when the class file is loaded.

If it is done at runtime then why can't the JVM figure out that they are the same String.

Because the string being returned by .substring has not been interned, and so is a different object than the equivalent "test" string in the string pool. If you interned it, you'd get true:

"test" == "!test".substring(1).intern() // true

Sections §4.4 of the JLS and §5.3 of the JVM spec look relevant.


Just to be clear: The correct way to compare strings in Java is to use the .equals method or similar, not ==. Using == with string instances is usually incorrect. (Unless you're playing with understanding when and how things are interned...)

like image 188
T.J. Crowder Avatar answered Oct 19 '22 07:10

T.J. Crowder