由于String类型被final修饰
每当改变String类型的值,其实已经创建了一个全新的String对象,比如进行String + = str,各种String方法,改变值
,不断的创建新的对象,会造成资源浪费问题。
JVM视角来看String常量池
在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
在JDK1.8 hotspot移除了永久代用元空间(Metaspace)取而代之, 这时候字符串常量池还在堆, 运行时常量池还在方法区, 只不过方法区的实现从永久代变成了元空间(Metaspace)
这里可以看到,堆中的常量池,常量池有常量池的优势,当我创建了一个String类型字符串,又用同样的快速方法创建了相同的值String a = 1;Stirng b = 1;
正常去思考String是对象,不同的创建一定不同,可是这种创建方式他们都放在常量池中,而不是常量池外,String str = new String(1);
这样的方式就会存在堆中的对象,并不会进入常量池中。
举个例子
String str1 = new String(“A”+“B”) ; 会创建多少个对象?
String str2 = new String(“ABC”) + “ABC” ; 会创建多少个对象?
str1:
字符串常量池:“A”,“B”,“AB” : 3个
堆:new String(“AB”) :1个
引用: str1 :1个
总共 : 5个
str2 :
字符串常量池:“ABC” : 1个
堆:new String(“ABC”) :1个
引用: str2 :1个
总共 : 3个
常量池的常量,可以反复使用
当反复使用一个 String可以将他的值放入常量池,反复获取。