问题
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.
回答1:
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...)
回答2:
I checked .class for
String a = "ABC";
String b = "ABC";
and found only one "ABC" in it. That is javac creates one constant of the same string at compile time.
But if 2 or more classes have the same "ABC" constant then JVM will place them at the same location in string pool
来源:https://stackoverflow.com/questions/29879179/is-string-interning-done-at-compile-time-in-java