其他分享
首页 > 其他分享> > 关于字符串拼接的字节码分析

关于字符串拼接的字节码分析

作者:互联网

1、从字符串拼接学习字节码分析

public class JvmTest {
    public void test() {
        String s4 = new String("hel") + "lo";
    }
}

先反汇编,到class文件所在目录打开控制台执行javap -c 类名

$ javap -c JvmTest
警告: 二进制文件JvmTest包含com.chen.base.jvm.JvmTest
Compiled from "JvmTest.java"
public class com.chen.base.jvm.JvmTest {
  public com.chen.base.jvm.JvmTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void test();
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup
       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       7: new           #4                  // class java/lang/String
      10: dup
      11: ldc           #5                  // String hel
      13: invokespecial #6                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
      16: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: ldc           #8                  // String lo
      21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      27: astore_1
      28: return
}

接下来一个指令一个指令的分析,为什么new String("hel") + "lo";创建了两个对象。

行号指令含义
13new堆中创建一个StringBuilder对象,并把堆中此对象地址压入栈顶
14dup复制栈顶的值,压入栈顶
15invokespecial初始化StringBuilder,对象创建都是先分配内存,再初始化
16new堆中创建一个String对象,并把堆中此对象地址压入栈顶
17dup复制栈顶的值,压入栈顶
18ldc从常量池取出字符串"hel"并压入栈顶
19invokespecial和前面一样,先分配地址,再调用String的初始化方法,把"hel"压入new的对象中,注意看19行注释,初始化时有传参(Ljava/lang/String;),15行是""

标签:lang,Ljava,java,字节,StringBuilder,栈顶,拼接,字符串,String
来源: https://blog.csdn.net/chen462488588/article/details/120675704