5

我知道当池中已经存在一个字符串时,将不会再创建一个新的字符串文字。

我也知道字符串常量池和堆之间的区别

我只想知道何时为以下示例的类创建字符串池。

String s="qwerty";
String s1="qwer"+"ty";// this will be resolved at compile time and no new string literal will be made

String s2=s.subString(1); will create qwerty at run time

s==s1; //true
s==s2;//false

我想知道 String s1 在编译时被解析,这是否意味着字符串池是在编译时创建的?

4

2 回答 2

9

常量池包含String实例,它们是运行时工件。显然,您不能在启动使用它们的程序之前创建对象。指定将创建哪些字符串常量的数据是在编译时准备的,并且是类文件格式的一部分。

但是,请注意字符串常量是在类加载时创建的,而不是在类初始化时或第一次使用时创建的。这是人们经常混淆的一点。

在您的示例中,区别不在编译时间和运行时之间,而是在常量池中创建一次字符串和每次执行一行代码时创建它。

另请注意,字符串池长期以来一直是 OpenJDK 中常规堆的一部分(甚至在它成为 OpenJDK 之前)。

于 2013-09-18T07:59:19.110 回答
1

根据您的代码:

String s2=s.subString(1); //this will create werty not qwerty so s==s2 will be anyways false

如果你使用

String s2=s.subString(0); //this will create qwerty 

然后s==s2会返回true

还有一种方法intern()可以查看以下情况的常量池:

String s2 = new String("Qwerty").intern();

在这种情况下,s==s2将返回,true 但如果String s2==new String("Qwerty");thens==s2将返回false

在 JDK 7 之前,字符串文字也是 permgen 空间的一部分,之后它们成为堆空间的一部分。

于 2013-09-18T08:54:45.733 回答