zoukankan      html  css  js  c++  java
  • Java 字节码解读

    1. 源代码

    2. 反编译class 文件
    3. 打开十六进制文件

    4. 解释

    一、源代码

    public class People {
    
        private String name;
        private int age;
    
    }

    二、利用Javap 反编译查看字节码结构信息

    javap  -v  People.class

    结果如下

    Classfile /D:/work/byte-code/src/People.class
      Last modified 2020-12-9; size 240 bytes
      MD5 checksum 54b8c1ad94a9c9cf5074fd8520454e9c
      Compiled from "People.java"
    public class People
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #3.#14         // java/lang/Object."<init>":()V
       #2 = Class              #15            // People
       #3 = Class              #16            // java/lang/Object
       #4 = Utf8               name
       #5 = Utf8               Ljava/lang/String;
       #6 = Utf8               age
       #7 = Utf8               I
       #8 = Utf8               <init>
       #9 = Utf8               ()V
      #10 = Utf8               Code
      #11 = Utf8               LineNumberTable
      #12 = Utf8               SourceFile
      #13 = Utf8               People.java
      #14 = NameAndType        #8:#9          // "<init>":()V
      #15 = Utf8               People
      #16 = Utf8               java/lang/Object
    {
      public People();
        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 5: 0
    }
    SourceFile: "People.java"

    三、利用Uedit 打开class 文件(新发现010 编辑器更好用)

    CA FE BA BE 00 00 00 34 00 11 0A 00 03 00 0E 07
    00 0F 07 00 10 01 00 04 6E 61 6D 65 01 00 12 4C
    6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67
    3B 01 00 03 61 67 65 01 00 01 49 01 00 06 3C 69
    6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64
    65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61
    62 6C 65 01 00 0A 53 6F 75 72 63 65 46 69 6C 65
    01 00 0B 50 65 6F 70 6C 65 2E 6A 61 76 61 0C 00
    08 00 09 01 00 06 50 65 6F 70 6C 65 01 00 10 6A
    61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 00
    21 00 02 00 03 00 00 00 02 00 02 00 04 00 05 00
    00 00 02 00 06 00 07 00 00 00 01 00 01 00 08 00
    09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00
    05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06
    00 01 00 00 00 05 00 01 00 0C 00 00 00 02 00 0D

    四、根据上述的十六进解释

    ca fe ba be  魔数
    00 00 次版本号
    00 34 主版本号
    00 11 常量池数量(17-1 = 1~16)
    0A 00 03 00 0E  #1 ,指向 #3 = #16 = java/long/Object,  指向#14
    07 00 0F #2  指向#15 = People
    07 00 10 #3  指向#16 = java/lang/Object
    07 01 00 04 #4
      6E 61 6D 65  //name
    01 00 12 #5
      4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B  // Ljava/lang/String;
    01 00 03 #6
      61 67 65 //age
    01 00 01 #7
      49  // I
    01 00 06 #8
      3C 69 6E 69 74 3E // <init>
    07 00 03 #9
      28 29 56 // ()V
    01 00 04 #10
      43 6F 64 65 // Code
    01 00 0F #11
      4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 //LineNumberTable
    01 00 0A #12
      53 6F 75 72 63 65 46 69 6C 65 // SourceFile
    01 00 0B #13
      50 65 6F 70 6C 65 2E 6A 61 76 61 //People.java
    0C 00 08 00 09 #14  指向 #8 = <init>, 指向 #9 = ()V
    01 00 06 #15
      50 65 6F 70 6C 65  //People
    01 00 10 #16
      6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 // java/lang/Object
    00 21 访问标志位
    00 02 当前类索引 #2
    00 03 父类索引 #3
    00 00 接口计数器
    00 02 字段计数器
    00 02 字段访问标志 //private
    00 04 字段名称 //#4 = name
    00 05 字段描述符 // #5 = String
    00 00 附属表
    00 02 字段描述符 //private
    00 06 字段名称   //age
    00 07 字段描述符  // I = int
    00 00 字段附属表
    00 01 方法计数器  //一个方法
    00 01 方法访问标志 //public
    00 08 方法名称 // <init>
    00 09 方法描述符 // ()V
    00 01 附属表计数器 // 方法一个附属表
    00 0A 附属表名称  #10 = code
    00 00 00 1D 附加属性长度 // 29
    00 01 //栈最大深度为1
    00 01 //临时变量数目为1
    00 00 00 05 //字节码长度以及指令
      2A //aload_0
      B7 00 01 //invokespecial #1 = Methodref #3 #14
      B1   // 表示return ,无返回值
    00 00 //异常个数为0
    00 01 //存在一个附加属性
    00 0B //属性名称 = #11
      00 00 00 06 // 附加属性长度
    00 01 //存在一个line_number_table
    00 00 //字节码 start_pc 为0
    00 05 //源代码行号 Line Number 对应为5
    00 01 //表示字节码附加属性个数为1
    00 0c #12 指向 SourceFile
    00 00 00 02 // SourceFile 属性后面所占字节为 2
    00 0D # SourceFile 的索引,#13 = People.java

     参考:https://blog.csdn.net/u012149894/article/details/105466996

     附录:

    常量池项目类型

     常量池中17种数据类型的结构总表

     

     

    访问标志

     字段表结构

     字段访问标志

     描述字符含义

     方法表结构

     方法访问标志

     属性表

     

     属性表结构

     Code 属性表结构

     Exception 属性结构

     LineNumberTable 属性结构

     SourceFile 属性结构

  • 相关阅读:
    《Java技术》第四次作业
    Java第三次作业——面向对象基础(封装)
    《Java技术》第二次作业
    #《Java技术》第一次作业
    Java第十次作业
    Java第九次作业
    Java第八次作业
    Java第七次作业
    Java第6次作业
    Java第五次作业
  • 原文地址:https://www.cnblogs.com/bytecodebuffer/p/14122533.html
Copyright © 2011-2022 走看看