String常量池和堆内存

String常量池和堆内存

详细内容请看以下链接,下面为简略摘抄
https://blog.csdn.net/sinat_33921105/article/details/82192094

首先,看下面一道经典题目:

1.下面代码中创建几个对象?

    String s1 = new String("hello");
    String s2 = new String("hello");

答案是3个,首先判断字符串常量池中是否有"hello"对象,没有的话先在字符串常量池中创建一个,然new String()的时候又会在堆内存中创建两个。

然后,再看下面稍微复杂点的
2.下面代码中,又创建了几个对象?

public class TestString {
    public static void main(String[] args) {

        String s1 = "Java";          //1
        String s2 = "从0到1";        //2
        String s3 = s1 + s2;        //3
        String s4 = "Java从0到1";   //4

        System.out.println(s3 == s4);


    }
}

正确答案为6个。
首先,我们知道1、2、4三行代码在字符串常量池中创建了3个对象,重点是第3行代码,在编译阶段时不能确定s3的值,只有在运行时才能确定s3的值是“Java从0到1”,而这个字符串对象因为不是在编译期确定下来的,因此不会被放到字符串常量池中,会被放到堆中,这就又一个对象。到这里,已经创建了4个对象,然而这还没有结束。
下面说说字符串常量池到底存在在哪个位置,在jdk1.6及之前在方法区中,但是在jdk1.7及以后就放在了堆中,我们现在一般很少使用jdk1.6及之前的版本,因此现在讨论所说的字符串常量池除非特别说明jdk版本,否则默认是在堆中。因此字符串常量池其实就在堆中。回到上面第3行代码,s3是由s1和s2相加得到的,因s3最终是在常量池之外的堆中形成的,而s1和s2都是在常量池中,因此会将s1和s2拷贝一份到字符串常量池之外的堆中来形成s3。如下图所示:
堆内存
因此加上两个拷贝的对象,上述代码中一共创建了6个对象!其中3个是编译时期创建在字符串常量池中的,1个是运行时期创建在字符串常量池之外的堆内存中,还有2个是从字符串常量池中拷贝到堆内存中的对象。

上面提到重点知识:
1.编译阶段确定的字符串才会被放到字符串常量池中。
2.字符串常量池在堆中。
3.运行阶段确定的字符串,如果需要字符串常量池中的对象,那么会拷贝一个对象到堆内存中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值