new String("abc")的详细流程

1.代码

jdk版本是1.8.0_111

代码如下:

对Test4.class的代码执行javap命令,如下:

执行后截图如下:

 

2.执行字节码指令的过程

第0行:

为str分配内存空间,并把该引用放到操作数栈中。

第3行:

复制操作数栈栈顶的元素,并放到操作数栈中。

第4行:

把指向常量池中引用(暂时为该引用命名为sym)放到操作数栈栈顶。

第6行:

调用String的String(String str)实例构造器,执行new String(sym),需要使用操作数栈的最上面的两个元素,并把new String()的引用放到操作数栈中。

第9行:

把栈顶的指向String实例的引用放到局部变量表的索引为1的位置中。

 

3.String的源码

可以看出来,value是一个char型数组,而且是final修饰的。

4.综合字节码指令和String源码

在第2小节中,可以看到new String("abc")其实是执行的是第6行的new String(sym),又因为sym为指向常量池中"abc"的引用,具体来说是因为sym是String类型(可以从常量池中的#18看出来),所以sym中有value数组,也就是value数组中存储的是"abc",所以在执行this.value = original.value时,是把sym中的value引用赋值给this.value。

new String("abc")相当于new String(sym)

value是数组,所以value也是引用,指向数组对象(这里的value是private的,但是original是String类型的且在String中调用,所以original.value可以直接调用,不会报编译时不可见错误)。

综上,在执行str = new String("abc")时,会在编译期时,在常量池中放入一个"abc",在执行期时,把str中的value指向常量池中的"abc"。所以图如下(图片来源:https://www.jianshu.com/p/2f209af80f84):

另外的StringBuilder和StringBuffer和String的区别的原因可通过同样的方式进行字节码查询,举例如下:

这就是当进行大量字符串连接时,不推荐使用string的原因,因为每次进行一条包含诸如s12 = s1 + s2;这样的操作,都是要在内存中创建一个StringBuilder或StringBuffer的操作。

而且String中的+号的实现通过字节码可以看出,+号在实现的过程就是执行append方法的过程。

 

参考:

浅谈Java String内幕:https://www.jianshu.com/p/2f209af80f84

Java字节码的介绍:https://blog.csdn.net/hj7jay/article/details/80014151

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值