Java记录 -26- StringPool和字面赋值

Java中的String类在开发中使用比较频繁,所以JDK的开发者对String类进行了很多优化。

Java中维护着一个StringPool字符串池的概念。

Java中String类的字面赋值和 new 赋值的不同。

1.      String a1 = "bb";
        String a2 = "bb";
        System.out.println(a1 == a2);

上面的输出结果为true,这是为什么呢?

StringPool(字 符串池),对于字符串来说,Java会维护者一个字符串池的概念。当使用字面量直接给一个字符串进行赋值的时候,实际上做了两件事情:首先检查字符串池中 有没有内容为该字符串内容的字符串存在,没有则将该字符串放入字符串池里,并创建字符串对象返回对象地址给引用;当再次赋值同一个字符串时会再次判断字符 串池里是有存在该字符串,存在则不会再创建对象而是直接将地址返回给引用。这样多个引用就会指向同一个对象。

2.String s = "aaa";

以上代码采用字面值的方式赋值需要执行以下几步操作:

1).查找StringPool中是否存在“aaa”这个对象,如果不存在,则在StringPool中创建一个“aaa”对象,然后将StringPool中“aaa”的地址返回,赋给引用变量s,这样s会指向StringPool中的这个“aaa”字符串对象。

2).如果存在则不创建任何对象,直接将StringPool中的这个“aaa”对象地址返回,赋给s引用。

3.      String s1 = new String("aa");
        String s2 = new String("aa");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));

上面的代码输出中第一个为false,第二个为true。第二个为true好理解,以前说过,String类的equals比较两个字符串的内容是否一致。但第一个为false,难道没有使用上面刚提到的StringPool吗?

内存主要区域为堆和栈,StringPool字符串池是在java的栈中,而我们new出来的对象都是在java的堆中。

4.String s = new String("aaa"); //String使用new来创建对象时,同样也利用了StringPool

1).首 先会在StringPool中查找是否存在“aaa”该字符串对象,如果存在则不会再在StringPool创建“aaa”这个对象了,而是会在堆中直接 去创建一个“aaa”字符串对象,并且将堆中创建的对象地址返回给s引用,导致s指向了堆中创建的这个“aaa”字符串对象;

2).如果不存,则首先会在StringPool中创建一个“aaa”字符串对象,然后再在堆中创建一个“aaa”字符串对象,并且将堆中创建的对象地址返回给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。

5.在使用new创建字符串时,不管StringPool中是否存在该字符串对象,在堆中都会创建一个该字符串对象,并返回地址给引用。所以new创建的字符串对象都是指向堆中的地址。

String特麻烦,针对不同的JDK实现,String的实现也不同。


你可能感兴趣的:(StringPool,Java记录,字面赋值)