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

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";创建了两个对象。

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

专注分享技术,共同学习,共同进步。侵权联系[admin#icode9.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有

上一篇:C#中手工进行声明式验证,从此远离if验证


下一篇:Deno + mongodb实现增删查改(CRUD)的restful接口