我知道当池中已经存在一个字符串时,就不会重新生成新的字符串了。
我知道字符串常量池和堆之间的区别
我只想知道何时为下面的示例创建了一个类的字符串池。
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在编译时被解析是否意味着字符串池是在编译时创建的?
答案 0 :(得分:8)
常量池包含String
个实例,它们是运行时工件。显然,在启动它们所使用的程序之前,不能创建对象。指定将创建字符串常量的数据是在编译时准备的,并且是类文件格式的一部分。
但是,请注意,字符串常量是在类 loading 时创建的,而不是在初始化类的时间或第一次使用时创建的。这是人们经常混淆的一点。
在您的示例中,差异不在编译时和运行时之间,而是在常量池中创建一次字符串,并在每次执行一行代码时创建它。
另请注意,在OpenJDK中,字符串池已经成为常规堆的一部分了很长时间(甚至在它成为OpenJDK之前)。
答案 1 :(得分:0)
根据您的代码:
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");
,则s==s2
将返回false
。
在JDK 7之前,字符串文字也是permgen空间的一部分,之后它们就成了堆空间的一部分。