class A {
String s4 = "abc";
static public void main(String[]args ) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
A o = new A();
String s5 = new String("def");
System.out.println("s1==s2 : " + (s1==s2));
System.out.println("s1==s1.intern : " + (s1==s1.intern()));
System.out.println("s1==s3 : " + (s1==s3));
System.out.println("s1.intern==s3.intern : " + (s1.intern()==s3.intern()));
System.out.println("s1==s4 : " + (s1==o.s4));
}
}
The output:
s1==s2 : true
s1==s1.intern : true
s1==s3 : false
s1.intern==s3.intern : true
s1==s4 : true
My questions:
1.What happens for "String s1 = "abc"? I guess the String object is added to the pool in class String as an interned string? Where is it placed on? The “permanent generation” or just the heap(as the data member of the String Class instance)?
2.What happens for "String s2 = "abc"? I guess no any object is created.But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?
3.Seems String s3 = new String("abc") does not use interned string.Why?
4.Will String s5 = new String("def") create any new interned string?
At compile time a representation of the literal is written to the “constant pool” part of the classfile for the class that contains this code.
When the class is loaded, the representation of the string literal in the classfile’s constant pool is read, and a new String object is created from it. This string is then interned, and the reference to the interned string is then “embedded” in the code.
At runtime, the reference to the previously created / interned String is assigned to
s1. (No string creation or interning happens when this statement is executed.)Yes. But not when the code is executed.
It is stored in the permgen region of the heap. (The String class has no static fields. The JVM’s string pool is implemented in native code.)
Nothing happens at load time. When the compiler created the classfile, it reused the same constant pool entry for the literal that was used for the first use of the literal. So the String reference uses by this statement is the same one as is used by the previous statement.
Correct.
No, and No. The Java interpretter (or JIT compiled code) uses the same reference as was created / embedded for the previous statement.
It is more complicated than that. The constructor call uses the interned string, and then creates a new String, and copies the characters of the interned string to the new String’s representation. The newly created string is assigned to
s3.Why? Because
newis specified as always creating a new object (see JLS), and theStringconstructor is specified as copying the characters.A new interned string is created at load time (for “def”), and then a new String object is created at runtime which is a copy of the interned string. (See previous text for more details.)