是否使用+串联创建的字符串存储在字符串池中?
例如
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.
不需要。只需要字符串文字即可进入池中。 编译器可以优化连接,并可以在池中存储其他字符串文字。