String的创建过程

String的创建过程

1. 直接使用双引号声明出来的String

1.1 创建逻辑说明

String str = "xyz";

创建说明

​ 在常量池中查看是否有xyz对象,如果不存在先在常量池创建xyz对象,创建后返回常量池中的xyz对象的引用给str;如果常量池中存在xyz对象则直接返回常量池中xyz对象的引用给str。

// 创建过程大致逻辑
if (常量池中存在内容为xyz对象/引用) {
    返回常量池中xyz对象/引用的引用给str
}
else if (常量池中不存在xyz对象/引用) {
    在常量池创建xyz对象;
    返回在常量池中创建的xyz对象的引用给str
}

该创建方式一共创建一个对象,为常量池中的xyz ,不在堆中创建任何对象

1.2 举例

String str1 = "xyz";
String str2 = "xyz";
System.out.println(str1 == str2); // true

创建过程

  1. 创建str1,在常量池中查看是否有xyz对象,发现没有,就在常量池中创建xyz对象,返回在常量池创建的xyz对象的引用。
  2. 创建str2,在常量池中查看是否有xyz对象,发现存在(是创建str1时创建的xyz对象),直接返回常量池中的xyz对象的引用。
  3. str1和str2都为str1创建时在常量池生成的xyz对象,为true
// jdk8
String str1 = new String("x") + new String("yz");
str1.intern();
String str2 = "xyz";
System.out.println(str2 == str1); // true

创建过程

  1. new String(“x”):常量池x, 堆new String(“x”)
  2. new String(“yz”):常量池x, 堆new String(“yz”)
  3. new String(“x”) + new String(“yz”):堆StringBuild, new String(“xyz”)
  4. str1.intern();:常量池没有内容为str1内容的对象/引用,将new String(“xyz”)的引用即str1写入常量池
  5. String str2 = “xyz”;:在常量池中查找内容为xyz的对象/引用,str1.intern()时写入的str1符合条件,返回str1的引用
  6. str2为str1的引用,str1又为new String(“xyz”)的引用,str2和str1都为new String(“xyz”),true.

2. new方法创建String

2.1 创建逻辑说明

String str = new String("xyz");

创建说明

​ 查看常量池中是否存在xyz对象,如果常量池中不存在xyz对象,在常量池中创建xyz对象,然后再在堆中创建new String(“xyz”)对象,返回new String(“xyz”)的引用给str;如果常量池中存在xyz对象,不在常量池中创建xyz对象,直接在堆中创建new String(“xyz”)对象,返回new String(“xyz”)的引用给str。

// 创建过程大致逻辑 
if (常量池中存在xyz对象/引用) {
    在堆中创建new String("xyz")对象;
    返回在堆中创建new String("xyz")对象的引用给str;
}
else if (常量池中不存在xyz对象/引用) {
   	在常量池中创建xyz对象;
    在堆中创建new String("xyz")对象;
    返回在堆中创建new String("xyz")对象的引用给str;
}
  • 该创建方式常量池存在创建一个对象(堆中创建的new String(“xyz”)对象)

  • 该创建方式常量池不存在创建两个对象(常量池xyz对象,堆中创建的new String(“xyz”)对象)

2.2 举例

String str1 = new String("xyz");
String str2 = new String("xyz");
System.out.println(str1 == str2); // false

创建过程

  1. 创建str1,在常量池中查看是否存在xyz对象,发现没有,在常量池中创建xyz对象,再在堆中创建new String(“xyz”)(下面用new String(“xyz”)-str1说明),将new String(“xyz”)的引用返回给str1。(创建了2个对象)
  2. 创建str2,在常量池中查看是否存在xyz对象,发现存在(是创建str1时创建的xyz对象)直接在堆中创建new String(“xyz”)(下面用new String(“xyz”)-str2说明),将new String(“xyz”)的引用返回给str2。 (创建了1个对象)
  3. str1为堆中new String(“xyz”)-str1对象的引用,str2为为堆中new String(“xyz”)-str2对象的引用,false。

创建完后对象分别为

  • 常量池(1个对象):xyz
  • 堆(2个对象):new String(“xyz”)-str1, new String(“xyz”)-str2

其他说明

​ str1为堆中new String(“xyz”)-str1对象的引用

​ str2为为堆中new String(“xyz”)-str2对象的引用

3. 两个引号相加

String str1 = "x" + "yz";
String str2 = "xyz";
System.out.println(str1 == str2); // true

创建过程

  1. str1在编译过程会进行优化,优化为str1 = “xyz”;所以该情况等价与1.2举例相同

创建完后对象分别为

  • 常量池(1个对象):xyz
  • 堆(0个对象)

其他说明

​ str1, str2为常量池中xyz对象的引用

4. 两个new相加

String str = new String("x") + new String("yz");

创建过程

  1. new String(“x”)/时:

    ​ 常量池的x,堆的new String(“x”)

  2. new String(“yz”)时:

    ​ 常量池的yz,堆的new String(“yz”)

  3. new String(“x”) + new String(“yz”)时:

    ​ 创建一个StringBuilder对象,调用append和toString在堆中生成一个new String(“x”) + new String(“yz”)对象(下面用new String(“xyz”)代替说明)

创建完后对象分别为

- 常量池(2个对象):x, yz 
- 堆(4个对象):new String("x") ,new String("yz"),StringBuilder,  new String("xyz")

其他说明

​ str为堆中new String(“xyz”)的引用

5. 一个引号加一个new

String str = "x" + new String("yz");

创建过程

  1. x时:

    ​ 常量池的x

  2. new String(“yz”)时:

    ​ 常量池的yz,堆的new String(“yz”)

  3. x + new String(“yz”)时:

    ​ 创建一个StringBuilder对象,调用append和toString在堆中生成一个x+ new String(“yz”)对象(下面用new String(“xyz”)代替说明)

创建完后对象分别为

  • 常量池(2个对象):x, yz
  • 堆(3个对象):new String(“yz”),StringBuilder, new String(“xyz”)

其他说明

​ str为堆中new String(“xyz”)的引用

6. 两个变量相加

有变量引用的字符串是不能优化的,除非变量是final修饰,具体查看代码例子的问题八

String x = "x";
String yz = "yz";
String str = x + yz;

创建过程

  1. x时:

    ​ 常量池的x

  2. yz时:

    ​ 常量池的yz

  3. str = x + yz时:

    ​ 创建一个StringBuilder对象,调用append和toString在堆中生成一个x + yz对象(下面用new String(“xyz”)代替说明)

创建完后对象分别为

  • 常量池(2个对象):x, yz
  • 堆(2个对象):StringBuilder, new String(“xyz”)

其他说明

​ str为堆中new String(“xyz”)的引用

参考链接:

https://blog.csdn.net/u013366617/article/details/83618361
代码例子

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值