For instance
String s = \"Hello\" + \" World\";
I know there are two strings in the pool \"Hello\" and \"World\" but, does: \"Hello World\
By way of confirming @Brian Agnew's answer, I looked at this code:
public class InternTest {
public static void main(String[] args) {
String s = "Hello" + ", world";
System.out.println(s);
}
}
This behavior is required for string literals and constant expressions which evaluate to a String
.
javap -c InternTest Compiled from "InternTest.java" public class InternTest extends java.lang.Object{ public InternTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2; //String Hello, world 2: astore_1 3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 6: aload_1 7: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 10: return
String hello = "Hello", lo = "lo";
// known at compile time so created in String constant pool
System.out.print((hello == "Hello") + " ");
// known at compile time so "Hello" is same object as in hello
System.out.print((Other.hello == hello) + " ");
// Other.hello and hello created at compile time so referenced to same object
System.out.print((other.Other.hello == hello) + " ");
// other.Other.hello and hello created at compile time
// so referenced to same object
System.out.print((hello == ("Hel"+"lo")) + " ");
// hello and "Hel"+"lo" both were created at compile
// time so referenced to same object
System.out.print((hello == ("Hel"+lo)) + " ");
// value in lo was not known in runtime so didn't
// referenced to object in hello, instead created new object in String Pool Constant
System.out.println(hello == ("Hel"+lo).intern());
// ("Hel"+lo).intern() using intern function told at runtime
// to check weather same string present in String Constant Pool,
// and if present then reference to the same string which was already present in String Constant Pool.
Yes, if a String
is formed by concatenating two String
literals it will also be interned.
From the JLS:
Thus, the test program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }
produces the output:
true
true
true
true
false
true
The important lines are 4 and 5. 4 represents what you are asking in the first case; 5 shows you what happens if one is not a literal (or more generally, a compile-time constant).
No. Only string literals are required to go into the pool. Compilers may optimize away the concatenation and may store additional string literals in the pool.
I believe in the first case the compiler will be clever and put the concatenated string in the pool (i.e. you'll have only 1 string there)
If I am wrong please correct me. As per my understanding only one object is going to be created in SCP. As String s = "Hello" + " World"; is a compile time constant.So compiler will append these two strings at compile time only.And only one object will be created in SCP. If you open and see .class file you will find "HelloWorld in .class file