Are strings created with + concatenation stored in the string pool?

感情迁移 提交于 2019-11-28 07:44:21

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).

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)

trashgod

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

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

Kiran P Fegade
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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!