一个简单的java字节码解析

Classfile /C:/workspace_2018/loadTest/src/byteTest/Hello.class
  Last modified 2021-1-12; size 987 bytes
  MD5 checksum 6193a13a7bd7a8eaf2993e2302ef6aa9
  Compiled from "Hello.java"
public class byteTest.Hello
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #12.#35        // java/lang/Object."<init>":()V
   #2 = Fieldref           #36.#37        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = Class              #38            // java/lang/StringBuilder
   #4 = Methodref          #3.#35         // java/lang/StringBuilder."<init>":()V
   #5 = String             #39            // a=
   #6 = Methodref          #3.#40         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #7 = Methodref          #3.#41         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #8 = Methodref          #3.#42         // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #9 = Methodref          #43.#44        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #10 = String             #45            // b=
  #11 = Class              #46            // byteTest/Hello
  #12 = Class              #47            // java/lang/Object
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Utf8               LineNumberTable
  #17 = Utf8               LocalVariableTable
  #18 = Utf8               this
  #19 = Utf8               LbyteTest/Hello;
  #20 = Utf8               main
  #21 = Utf8               ([Ljava/lang/String;)V
  #22 = Utf8               i
  #23 = Utf8               I
  #24 = Utf8               args
  #25 = Utf8               [Ljava/lang/String;
  #26 = Utf8               a
  #27 = Utf8               b
  #28 = Utf8               arr
  #29 = Utf8               [I
  #30 = Utf8               StackMapTable
  #31 = Class              #25            // "[Ljava/lang/String;"
  #32 = Class              #29            // "[I"
  #33 = Utf8               SourceFile
  #34 = Utf8               Hello.java
  #35 = NameAndType        #13:#14        // "<init>":()V
  #36 = Class              #48            // java/lang/System
  #37 = NameAndType        #49:#50        // out:Ljava/io/PrintStream;
  #38 = Utf8               java/lang/StringBuilder
  #39 = Utf8               a=
  #40 = NameAndType        #51:#52        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #41 = NameAndType        #51:#53        // append:(I)Ljava/lang/StringBuilder;
  #42 = NameAndType        #54:#55        // toString:()Ljava/lang/String;
  #43 = Class              #56            // java/io/PrintStream
  #44 = NameAndType        #57:#58        // println:(Ljava/lang/String;)V
  #45 = Utf8               b=
  #46 = Utf8               byteTest/Hello
  #47 = Utf8               java/lang/Object
  #48 = Utf8               java/lang/System
  #49 = Utf8               out
  #50 = Utf8               Ljava/io/PrintStream;
  #51 = Utf8               append
  #52 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #53 = Utf8               (I)Ljava/lang/StringBuilder;
  #54 = Utf8               toString
  #55 = Utf8               ()Ljava/lang/String;
  #56 = Utf8               java/io/PrintStream
  #57 = Utf8               println
  #58 = Utf8               (Ljava/lang/String;)V
{
  public byteTest.Hello();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LbyteTest/Hello;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=5, args_size=1
         0: iconst_1                         //加载一个静态常量(1)到操作数栈
         1: istore_1                          //将操作数栈栈顶的数值加载到局部变量表下标为(1)的位置上
         2: bipush        10                //将单字节的常量值(10)推送至栈顶
         4: istore_2                          //将操作数栈栈顶的数值加载到局部变量表下标为(2)的位置上
         5: iconst_4                          //加载一个静态常量(4)到操作数栈
         6: newarray       int               //该指令首先从操作数栈中加载栈定数据(4),并创建一个大小为该数据的数组,并将该数组的对象引用放入操作数栈中
         8: dup                                   //拷贝一份栈顶的值,并将其压栈,例如栈顶的值刚开始为value,执行完为value,value
         9: iconst_0                          //加载一个静态常量(0)到操作数栈  第一个数组元素下标
        10: iconst_1                          //加载一个静态常量(1)到操作数栈  第一个数组元素
        11: iastore                             //将栈顶int型数值存入指定本地变量  先存放数组引用
        12: dup                                 //复制栈顶数值并将复制值压入栈顶
        13: iconst_1                          //加载一个静态常量(1)到操作数栈 数组元素3的下标
        14: iconst_3                          //加载一个静态常量(3)到操作数栈 数组元素3
        15: iastore                            //将栈顶int型数值存入指定本地变量  先存放数组引用
        16: dup                                 //复制栈顶数值并将复制值压入栈顶
        17: iconst_2                          //加载一个静态常量(2)到操作数栈 数组元素6的下标
        18: bipush        6                   //将单字节的常量值(6)推送至栈顶   数组元素6
        20: iastore                             //本地将栈顶int型数值存入指定变量  先存放数组引用
        21: dup
        22: iconst_3
        23: iconst_4
        24: iastore
        25: astore_3                          //将操作数栈栈顶的数值加载到局部变量表下标为(3)的位置上  数组的引用
        26: iconst_0                          //本地将栈顶int型数值存入指定变量表下标为(4)位置上    i的值
        27: istore        4                     //将栈顶引用型数值存入第5个局部变量表 下标为(4)
        29: iload         4                     //加载操作数栈中第5个引用 的值   i的值
        31: aload_3                           //将第4个引用类型本地变量加载到操作栈           数组的引用
        32: arraylength
        33: if_icmpge     66               //比较栈顶两个int类型数值的大小 ,当前者  大于等于  后者时,跳转66   i< arr.length
        36: iload         4
        38: iconst_2
        39: irem                              //将栈顶两int型数值作取模运算并将结果压入栈顶            i%2
        40: ifne          48                  //当栈顶int型数值不等于0时跳转 48
        43: iload_1
        44: iload         4                   //加载i的值
        46: iadd                               //a+i
        47: istore_1                         //将操作数栈栈顶的数值加载到局部变量表下标为(1)的位置上  a的值
        48: iload         4
        50: iconst_2
        51: idiv                                //栈顶两int型数值作除法运算并将结果压入栈顶            i/2
        52: ifne          60                  //当栈顶int型数值不等于0时跳转 66
        55: iload_2
        56: iload         4
        58: isub
        59: istore_2
        60: iinc          4, 1                  //将第3个slot位置所在的int类型的本变量自增1
        63: goto          29
        66: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        69: new           #3                   // class java/lang/StringBuilder
        72: dup
        73: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
        76: ldc           #5                   // String a=
        78: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        81: iload_1
        82: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        85: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        88: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        91: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        94: new           #3                  // class java/lang/StringBuilder
        97: dup
        98: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
       101: ldc           #10                 // String b=
       103: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       106: iload_2
       107: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       110: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       113: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       116: return
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 5
        line 9: 26
        line 10: 36
        line 11: 43
        line 13: 48
        line 14: 55
        line 9: 60
        line 17: 66
        line 18: 91
        line 19: 116
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           29      37     4     i   I
            0     117     0  args   [Ljava/lang/String;
            2     115     1     a   I
            5     112     2     b   I
           26      91     3   arr   [I
      StackMapTable: number_of_entries = 4
        frame_type = 255 /* full_frame */
          offset_delta = 29
          locals = [ class "[Ljava/lang/String;", int, int, class "[I", int ]
          stack = []
        frame_type = 18 /* same */
        frame_type = 11 /* same */
        frame_type = 250 /* chop */
          offset_delta = 5
}
SourceFile: "Hello.java"

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值