10分钟搞懂String 堆内存和常量池

 


有了目标,就赶紧行动


注意:每new一个“ab”,就代表堆内存中出现了新的“ab”,但是常量池中只会有一份”ab";

所以这个问题你只需要看懂是堆内存中的还是常量池中的

具体细节参考博客  https://blog.csdn.net/vegetable_bird_001/article/details/51278339


        String s1  = "ab" ;//常量池中没有,所以系统在堆内存中申请一份,再放常量池一份,因为没有明显的说new,所以要的是常量池的那一份

        String s2  = "ab";//注意这个也没有明显的new,所以他要的是常量池中的那一份,先去常量池中找,常量池中有了,所以说s2和 s1都指向常量池中相同的那一份 “ab”

 

        System.out.println(s1 == s2); //true

        String s3 = new String("ab");//有new关键字,所以在堆内存中重新申请了一份“ab"   s1是常量池的那一份
        System.out.println(s1 == s3);//false

 例子1:

        String s4 = "a" + "b";//没有new 要的是常量池的那一份
        System.out.println(s1 == s4);//true  

例子2: 

       //和第三个代码段做对比

        String s5 = "a" ;
        String s6 = s5 + "b";//s6在堆内存中重新申请了一份”ab",而s1是常量池的那一份
        System.out.println(s1 == s6);//false

解释:你可以看到第一个例子当中String s4 = "a" + "b",因为java有常量优化的机制,在把java文件编译成class文件时,这行代码其实变成了String s4 = "ab",很明显 s1 = s4共享 "ab" 这个字符串,所以返回true。但是第二个例子可就不是这样了,s5 是一个变量,它指向字符串常量 “a” 。因为变量可以改变指向,那么在编译String s6 = s5 + “b”的时候 jvm 肯定不会认为String s6 = "ab" ,也就没有共享常量池中的 "ab"  那么一说,所以会为s6 创建一个全新的对象。因此 "ab"  和 s6并不是同一个对象,== 比较自然会返回false。 

补充:这里再记录一个常量优化的例子:

	byte num1 = 1;
	byte num2 = 3;
	byte num3 = num1 + num2;

  第三行代码对不对那?可以肯定的说,会报错。因为 byte/short/char 类型的数据在进行数学运算的时候 会自动被提升为 int 类型,第三行代码就相当于 byte = int + int。用byte接收int,肯定不行。再看下面这行代码:

	byte num= 1 + 2;

        我们都知道 整型数据默认就是 int,这行代码难道不相当于byte = int + int 吗?其实不是,因为常量优化机制的存在,在编译成class文件后,这行代码实际上变成了 byte = 3,3 没有超过byte的范围,所以不会报错。如果写byte num= 127 + 1,超出了 byte范围,那么就会报错。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值