String Literal Pool

我一直没有闹懂,String Literal Pool和String Constant Pool是否是同一回事。各种资料的查阅也都语焉不详,估计当作一回事吧。首先String的特性有如下代码可以说明:

public static void main(String args[]) {
    String s = "test";
    String s1 = "test";
    String s2 = new String("test");
    System.out.println(s == s1);//true
    System.out.println(s.equals(s1));//true

    System.out.println(s == s2);//false
    System.out.println(s.equals(s2));//true
}

s和s1引用和内容都相同,是因为有String Literal Pool存在的缘故,那何为String Literal Pool

String Literal Pool

为了述说简单期间,本文将以SLP代替String Literal Pool。SLP是一个存放String 对象引用的集合,而不是存放的是String对象。SLP早先是存在PerGen space中(有文档说jdk1.7开始存在heap中,待验证)

字符串方式定义String

当使用字符串形式创建String对象时,首先会检查SLP中是否有该字符串的引用存在,如果存在直接将该引用返回。这就解释了s和s1引用也相同的原因。 如:

String s = "test";
String s1 = "test";
System.out.println(s == s1);//true
System.out.println(s.equals(s1));//true

好处:这样做可以保证相同字符串不被重复分配内存空间,从而提高效率。并且由于“test”String的对象引用始终存放在SLP中,这也保证了他不会被轻易GC。

new方式创建String

当使用new 创建String时,将忽略SLP中是否存在对应字符串的引用,而直接在heap中创建一个新对象,并返回新引用,所以这会导致s和s2引用值不等,如下:

String s = "test";
String s2 = new String("test");
System.out.println(s == s2);//false
System.out.println(s.equals(s2));//true

效果图