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

时间:2010-06-12 16:02:31

标签: java string language-features

例如

 String s = "Hello" + " World";

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

如果是这样,怎么样?

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

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

6 个答案:

答案 0 :(得分:11)

是的,如果通过连接两个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") + " ");
        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"; }

产生输出:

true
true
true
true
false
true

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

答案 1 :(得分:4)

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

答案 2 :(得分:1)

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

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

评估为String的{​​{3}}和string literals需要此行为。

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

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

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.

答案 5 :(得分:-2)

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