package design.wlb.studyjava.demo.restudy.c4jvm专题.chapter02.c29StringTable_字符串变量拼接;
public class Client {
//StringTable["a","b","ab"](懒加载)
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2; //由javap反编译可知,它是new了StringBuilder对象,再执行了toString()方法【 return new String(value, 0, count);】,创建了一个新的字符串对象
System.out.println(s4==s3);
}
}
我们来看上面这段代码,s4 == s3 最后会输出什么结果?
答案是:false ,为什么呢?
通过javap命令反编译可知,s1 + s2 ,jvm对其做的操作是,使用StringBuilder将其两个字符串进行一个拼接,最后通过toString的方法得到一个字符串对象,因为toString里面的方法实现是return new String(value,0,count);它是通过new关键字创建的ab,这个存在与“非串池的堆中”。
在前面17章里面,我们知道在通过new 关键字创建的对象都在堆中。
在前面22章里面,我们知道了在jdk1.6中,StringTable串池在常量池在方法区中,jdk1.8中,常量池在元空间不归jvm管理,但串池不在常量池中,是在堆中。
当然jdk1.6方法区逻辑上是在堆里面,jdk 1.8方法区在元空间,但串池在堆里。
串池和普通的堆对象存的东西不一样。一个是存字符串常量,另一个存java对象的地址引用。当然字符串对象可以调用intern()方法,将其存入串池中。这个后面有所讲解。
好,这里就先讲到这。
17章传送阵:17.jvm内存结构部分——堆_tgbyhn31的博客-CSDN博客
22章传送阵:22.jvm内存结构部分——方法区_定义_tgbyhn31的博客-CSDN博客
上一篇:28.jvm内存结构部分——StringTable_常量池与串池的关系_tgbyhn31的博客-CSDN博客
下一篇:30.jvm内存结构部分——StringTable编译期优化_tgbyhn31的博客-CSDN博客



