String字符串难点

public class Demo {
    public static void main(String args[]) {
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = "hello";
        String str4 = "hello";
        String str5 = "he"+"llo";
        String str6 = "he";
        String str7 = "llo";
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str3==str4);
        System.out.println(str3=="hello");
        System.out.println(str4==(str6+str7));
    }
}

运行结果:
false
false
true
true
false

内存分布如下:

在这里插入图片描述

1.String str1 = new String(“hello”);

1.New的对象都会放在堆里面。
2.无论常量池内是否有“hello”字符串,都会在堆内开辟新空间创建new对象。
3.在执行前会在常量池中查看是否有一个"helllo"的对象,然后执行该行代码时new一个"hello"的对象存放在堆区中
4.若常量池中没有该字符串,就会在常量池中创建“hello”字符串,若有,就不用。并且new的对象指向常量池,栈内再创建str1和str2分别指向堆中的new对象,str1和str2都是引用,存的是地址,而不是对象。
所以

 System.out.println(str1==str2);//false
2. String str3 = “hello”;

java首先会在常量池里面找是否有“hello”字符串,若没有,则在常量池内创建“hello”字符串;若有,就不会再重新创建。再在栈内创建指向“hello”字符串的引用,所以str3和str4其实指向的是同一个对象。
str1指向堆区的对象,str3指向常量池中的对象,两个引用指向的地址不同,输入false;

System.out.println(str1==str3);//false
System.out.println(str3==str4);//true
3.String str5 = “he”+“llo”;

编辑器会将其优化为“hello”,然后在常量池里面找是否有字符串“hello”,如存在,就将str5指向“hello”,所以str5与str3的地址是相同的。

System.out.println(str3==str4);//true
4.String str8 = str6+str7;
  String str6 = "he";
  String str7 = "llo";
  String str8 = str6+str7;

这段代码总共创建了5个对象,字符串池中两个、堆中三个
str8由两个字符串变量串联。+运算符会在堆中建立来两个String对象,这两个对象的值分别是"he"和"llo",也就是说从字符串池中复制这两个值,然后在堆中创建两个对象,然后再建立对象str8,然后将"hello"的堆地址赋给str3

5.String str9 = str6+“llo”;

由于在字符串的"+"连接中,有字符串引用存在,而引用的值str6在程序编译期是无法确定的,即str6+"llo"无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给str9。

String str8 = str6+str7;
String str9 = str6+“llo”;

其实有点类似,str8=new StringBuffer(str6).append(str7).toString(),str9=new StringBuffer(str6).append(“34”).toString(),从上面可以看出str8和str9都开辟了新的内存空间来存放新的字符串“hello”,因此和str3的地址不同,str8和str9的地址也不相同。

参考链接
有争议的:https://www.cnblogs.com/gxyandwmm/p/9495923.html
参考:https://blog.csdn.net/Oct31_Dec25/article/details/83351206
https://www.cnblogs.com/javaminer/p/3923484.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值