一、关于常量池
字符串在Java中用的非常得多,Jvm为了减少内存开销和提高性能,使用字符串常量池来进行优化。
在jdk1.7之前(不包括1.7),Java的常量池是在方法区的地方,方法区是一个运行时JVM管理的内存区域,是一个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态常量等。
运行时常量池是方法区的一部分。
来看一个图:
(图片来自https://www.cnblogs.com/ysocean/p/8571426.html)
关于其他的内存分布就不在这介绍了。
而在jdk1.7和它以后,方法区的常量池被移到了堆中,见图:(图片来自https://www.cnblogs.com/ysocean/p/8571426.html)
二、new String("xxx")和 = "xxx"
在了解常量池后,我们再来看这两个创建String对象的方法。
先来看使用引号""创建字符串的方式
所以看这个例子:
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);//true
这个例子的结果是true,首先 String str1 = "hello",会先到常量池中检查是否有“hello”的存在,发现是没有的,于是在常量池中创建“hello”对象,并将常量池中的引用赋值给str1;第二个字面量 String str2 = "hello",在常量池中检测到该对象了,直接将引用赋值给str2。
然后是new的方式创建字符串