java字节码解析学习

Bertha 。 2021-12-24 10:31 394阅读 0赞

java字节码表

java源码:

  1. public class TestByteCode {
  2. public static void test() {
  3. int a = 10;
  4. int b = 10;
  5. int c = (a+b)*10;
  6. System.out.println(c);
  7. }
  8. public static void main(String[] args) {
  9. // TODO Auto-generated method stub
  10. String s = new String("aaaa");
  11. test();
  12. }
  13. }

编译出的class通过javap -c TestByteCode.class解析出的字节码:

  1. public class com.learn.test.code.bytecode.TestByteCode {
  2. public com.learn.test.code.bytecode.TestByteCode();
  3. /*这段是构造函数*/
  4. Code:
  5. /*加载了操作数栈中栈顶的引用*/
  6. 0: aload_0
  7. /*invokespecial指的是调用父类的构造方法,完成实例初始化,#1是构造方法地址,应该指向方法区*/
  8. 1: invokespecial #1 // Method java/lang/Object."<init>":()V
  9. /*返回空,如果是ireturn就是返回int,areturn返回引用,lreturn返回long型*/
  10. 4: return
  11. /*test方法部分字节码*/
  12. public static void test();
  13. Code:
  14. 0: bipush 10 /*把int型的10push到操作树栈栈顶*/
  15. 2: istore_0 /*把栈顶的10出栈存放到局部变量表中的0号变量*/
  16. 3: bipush 10 /*把int型的10push到操作树栈栈顶*/
  17. 5: istore_1 /*把栈顶的int型的10出栈存放到局部变量表中的0号变量*/
  18. 6: iload_0 /*加载int型的0号局部标量到栈顶*/
  19. 7: iload_1 /*加载int型的1号局部标量到栈顶*/
  20. 8: iadd /*把栈顶的两元素弹出并相加放到栈顶*/
  21. 9: bipush 10 /*把int型的10压到栈顶*/
  22. 11: imul /*把栈顶的两元素弹出并相乘放到栈顶*/
  23. 12: istore_2 /*把栈顶的int型数据出栈存放到局部变量表中的2号变量*/
  24. /*getStatic获得指定类的静态域,并将值压如栈顶,#2为地址*/
  25. 13: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
  26. 16: iload_2 /*把局部变量表中的2号变量加载到栈顶*/
  27. /*invokevitual 调用实例方法*/
  28. 17: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
  29. 20: return /*返回空*/
  30. public static void main(java.lang.String[]);
  31. Code:
  32. 0: new #4 // class java/lang/String /*创建一个对象并压入栈顶*/
  33. 3: dup /*复制栈顶数值并将复制值压入栈顶*/
  34. 4: ldc #5 // String aaaa /*将 int, float 或 String 型常量值从常量池中推送至栈顶*/
  35. /*invokespecial调用构造函数,调用String的构造函数*/
  36. 6: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V
  37. 9: astore_1 /*把引用存放到当前栈帧的1号局部变量*/
  38. 10: invokestatic #7 // Method test:()V /*调用静态方法*/
  39. 13: return
  40. }

常用的Java字节码指令有:

  1. 加载到操作数栈
    bipush 加载常量到操作数栈顶
    iload 将int型局部变量加载到栈顶
    lload 将long型局部变量加载到栈顶
    iconst_0 将int型0加载到栈顶
    fconst_0 将float型加载到栈顶
    ldc 加载常量池中数据到栈中
  2. 存储
    istore 将栈顶int出栈并存放到局部变量中
    fstore 将栈顶float出栈并存放到局部变量中
  3. 计算
    iadd ladd fadd dadd 栈顶两操作数操作,int或long等,结果压栈顶
    isub lsub fsub dsub 减法
    imul lmul fmul 乘法
    idiv ldiv fdiv 除法
    irem lrem 取模
    ineg lneg 取非
    ishl 左位移
    ifeq ifne 比较
  4. 调用相关
    getstatic 获取指定类的静态域,并入栈
    invokespecial 调用超类构造方法,实例初始化方法,私有方法。
    invokestatic 调用静态方法。
    “invokeinterface” 调用接口方法。
    invokedynamic 调用动态链接方法
  5. 内存分配
    new 创建一个对象,并将其引用值压入栈顶。
    newarray 创建一个指定原始类型(如 int、 float、 char??)的数组,并将其引用值压入栈顶
  6. 返回
    ireturn 从当前方法返回 int。
    lreturn 从当前方法返回 long。
    freturn 从当前方法返回 float。

有了这些基本能读懂些字节码了

发表评论

表情:
评论列表 (有 0 条评论,394人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java字节

    Java字节码是Java源代码经过编译器编译生成的二进制格式,它是一种面向栈的指令集架构。Java字节码由一系列指令组成,用于执行各种操作,如加载和存储数据、进行算术和逻辑运算

    相关 java字节

    小介:去年在读《深入解析JVM》的时候写的,记得当时还想着用自己的代码解析字节码的,最后只完成了一部分。现在都不知道还有没有保留着,貌似Apache有现成的BCEL工程可以做这

    相关 jvm字节解析i++和++

    i++和++i是编码中比较常用的代码,并且也是初学者容易混淆的。我们知道i++是先赋值再+自己,而++i是先+自己再赋值。为什么是这样呢?他们之间效率对比又是怎么样呢?本文我们