是否使用+串联创建的字符串存储在字符串池中?

例如

String s = "Hello" + " World"; 

我知道池中有两个字符串“Hello”和“World”但是,“Hello World”进入字符串池吗?

如果是这样,怎么样?

 String s2 = new String("Hola") + new String(" Mundo"); 

每种情况下池中有多少个字符串?

是的,如果通过连接两个String 文字形成一个String ,它也将被实现。

来自JLS:

因此,测试程序由编译单元组成(第7.3节):

 package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); // 1 System.out.print((Other.hello == hello) + " "); // 2 System.out.print((other.Other.hello == hello) + " "); // 3 System.out.print((hello == ("Hel"+"lo")) + " "); // 4 System.out.print((hello == ("Hel"+lo)) + " "); // 5 System.out.println(hello == ("Hel"+lo).intern()); // 6 } } class Other { static String hello = "Hello"; } and the compilation unit: package other; public class Other { static String hello = "Hello"; } 

产生输出:

 true //-> 1 true //-> 2 true //-> 3 true //-> 4 false //-> 5 true //-> 6 

重要的行是4和5. 4代表你在第一种情况下要求的; 图5显示了如果一个不是文字(或更一般地,编译时常量)会发生什么。

我相信在第一种情况下编译器会很聪明并将连接的字符串放在池中(即你只有 1个字符串)

通过确认@Brian Agnew的答案,我查看了这段代码:

 public class InternTest { public static void main(String[] args) { String s = "Hello" + ", world"; System.out.println(s); } } 

对于字符串文字和计算为String 常量表达式 ,此行为是必需的。

 javap -c InternTest
编译自“InternTest.java”
公共类InternTest扩展java.lang.Object {
 public InternTest();
  码:
    0:aload_0
    1:invokespecial#1;  //方法java / lang / Object。“”:()V
    4:回归

 public static void main(java.lang.String []);
  码:
    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;  //方法java / io / PrintStream.println:(Ljava / lang / String;)V
    10:回归

如果我错了,请纠正我。 根据我的理解,SCP中只会创建一个对象。 As String s =“Hello”+“World”; 是一个编译时常量。所以编译器只会在编译时追加这两个字符串。在SCP中只会创建一个对象。 如果打开并查看.class文件,您将在.class文件中找到“HelloWorld”

 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. 

不需要。只需要字符串文字即可进入池中。 编译器可以优化连接,并可以在池中存储其他字符串文字。