浅谈String的intern方法

一.问题引入

今天被同事问到一个问题:以下两段代码为什么返回结果不同

String s1= new String("a") + new String("b");

String s2 = s1.intern();

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

String s3 = new String("fg");

String s4 = s3.intern();

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

二.思考问题

分析以上问题,不难看出两段代码的结果不同就是第一行代码导致的,所以问题的本质就转变为new String("a") + new String("b")和new String("fg")到底有什么区别,进一步分析就发现问题关键在于new String("abc")的时候,StringTable中是否会创建对象,上网去查了一下发现答案不一致,于是亲自去实践了一番,发现流程是这样的,字面量“abc”会在字节码的常量池中,但是基于String的懒加载机制,这时候“abc”还仅仅是符号,而不是对象,执行到new的这一行才真正转变为字符串对象,并被放入字符串常量池中,然后会通过new String创建一个对象放入堆中,所以执行new String("abc")其实是创建了两个对象。

三.解决问题

基于以上我们就不难分析出问题的结果:

  1. 第一段代码中实际创建了这样几个对象:StringTable中的“a”,"b",堆中创建的new String("a")和new String("对象"),用于字符串拼接的StringBuilder对象,创建完成后调用toString方法生成的对象,相当于new String("ab"),关键就在于这个对象是不会在StringTable创建的,所以当执行s1.intern方法时,就会在StringTable中创建“ab”,并返回它的引用也就是s1,故为true

执行intern方法前:

执行intern方法后:

  1. 第二段代码实际创建了两个对象,StringTable中的“fg”和堆中创建的new String("fg"),调用s3.intern方法返回的就是池中的那个对象,这和堆中的对象显然不是同一个,故为false 如下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值