标签:stringpool java记录 字面赋值
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记录 字面赋值
原文地址:http://zlfwmm.blog.51cto.com/5892198/1694277