String的理解

转载(https://juejin.im/entry/6844903544999395342)

在jdk 1.7之后,方法区的字符串常量池移至堆中

1.使用 ” ” 双引号创建 : String s1 = “first”;
2.使用字符串连接符拼接 : String s2=”se”+”cond”;
3.使用字符串加引用拼接 : String s12=”first”+s2;
4.使用new String(“”)创建 : String s3 = new String(“three”);
5.使用new String(“”)拼接 : String s4 = new String(“fo”)+”ur”;
6.使用new String(“”)拼接 : String s5 = new String(“fo”)+new String(“ur”);

String的理解_第1张图片

Java 会确保一个字符串常量只有一个拷贝。
 
String s1 = “first”;
s1 : 中的”first” 是字符串常量,在编译期就被确定了,先检查字符串常量池中是否含有”first”字符串,
若没有则添加”first”到字符串常量池中,并且直接指向它。所以s1直接指向字符串常量池的”first”对象。

String s2=”se”+”cond”;
s2 :“se”和”cond”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,
所以s2也同样在编译期就被解析为一个字符串常量,并且s2是常量池中”second”的一个引用。

String s12=”first”+s2;
s12 : JVM对于字符串引用,由于在字符串的”+”连接中,有字符串引用存在,而引用的值在程序编译期是无法
确定的,即("first"+s2)无法被编译器优化,只有在程序运行期来动态分配使用StringBuilder连接后的
新String对象赋给s12。 
(编译器创建一个StringBuilder对象,并调用append()方法,最后调用toString()创建新String对象,
以包含修改后的字符串内容)

String s3 = new String(“three”);
s3 用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入
常量池中,
它们有自己的地址空间。 
但是”three”字符串常量在编译期也会被加入到字符串常量池(如果不存在的话)

String s4 = new String(“fo”)+”ur”;
s4 : 同样不能在编译期确定,但是”fo”和”ur”这两个字符串常量也会添加到字符串常量池中,
并且在堆中创建String对象。(字符串常量池并不会存放”four”这个字符串)

String s5 = new String(“fo”)+new String(“ur”);
s5 : 原理同s4。

你可能感兴趣的:(Java基础)