![在这里插入图片描述](https://img-blog.csdnimg.cn/2019081712315163.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNzI5OTcx,size_16,color_FFFFFF,t_70)**
*String 类在java源码中是定义为final的意味着它是一个常量; String c=“java”+“c++”;这条语句首先在编译阶段(也就是生成class文件阶段)编译器会识别出"java"和"c++“是一个字符串常量;编译器会做常量的运算,生成"javac++”,然后编译成class文件,文件中String c的值已经变成"javac++”;然后class文件进入运行阶段,由类加载器加载载进内存中,java虚拟机会为常量分配内存空间,而字符串常量"javac++"会被放进字符串常量池中 此时javac++已经是一个对象了,所以字符串常量池的字符串都是可以认为是new出来的;然后将"javac++"的地址值赋值给变量String c,此时c指向字符串“javac++”在字符串常量池的地址值。
下面是一张将以上变量设置为常量的图运算的结果
在这里或许有人要问了!String a=new String(“java”);在内存中又是怎么样呢? 首先此字符串是new出来的;所以编译期间不会运算;,在运行期间;jvm为此字符串在堆中开辟 一块内存空间,jvm先会在字符串常量池中找有没有叫“java”的字符串,如果没有会在字符串常量池中new出一个“java” 字符串常量,然后把这个常量的地址值传回给堆空间的引用。所以new String(“java”);里面放的是字符串常量池里面“java”的地址值。
来源:https://blog.csdn.net/qq_43729971/article/details/99691619