Java二进制字节码解读

解析后字节码

运行命令:javap -v 类名或者类全路径

Classfile /class文件路径
  Last modified 2022-5-12; size 556 bytes
  MD5 checksum 87970f58aeaa06be9b4af0063cde7e87
  Compiled from "JvmClassByteCode.java"
  
// 类基本信息
public class com.tigerkin.jvm.JvmClassByteCode
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
  
// 常量池
Constant pool:
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()V
   // 属性引用
   // #21.#22:在常量池找到第21个常量和第22个常量,得到:#28.#29:#30,最终得到:java/lang/System.out:Ljava/io/PrintStream;
   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #23            // Hello JVM ClassByteCode
   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #26            // com/tigerkin/jvm/JvmClassByteCode
   #6 = Class              #27            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/tigerkin/jvm/JvmClassByteCode;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               JvmClassByteCode.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = Class              #28            // java/lang/System
  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #23 = Utf8               Hello JVM ClassByteCode
  #24 = Class              #31            // java/io/PrintStream
  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V
  #26 = Utf8               com/tigerkin/jvm/JvmClassByteCode
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Utf8               java/io/PrintStream
  #32 = Utf8               println
  #33 = Utf8               (Ljava/lang/String;)V
{
  // 类构造方法信息
  public com.tigerkin.jvm.JvmClassByteCode();
    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 9: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/tigerkin/jvm/JvmClassByteCode;

  // 方法信息
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         // getstatic:获取一个静态变量
         // #2:在常量池中找到第二个常量
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         // ldc:将常量压入操作数栈中
         // #3:在常量池中找到第三个常量
         3: ldc           #3                  // String Hello JVM ClassByteCode
         // invokevirtual:调用虚方法
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 11: 0
        line 12: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "JvmClassByteCode.java"

二进制字节码

00000000h: CA FE BA BE 00 00 00 34 00 22 0A 00 06 00 14 09
00000010h: 00 15 00 16 08 00 17 0A 00 18 00 19 07 00 1A 07
00000020h: 00 1B 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29
00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E
00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63
00000050h: 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01
00000060h: 00 04 74 68 69 73 01 00 23 4C 63 6F 6D 2F 74 69
00000070h: 67 65 72 6B 69 6E 2F 6A 76 6D 2F 4A 76 6D 43 6C
00000080h: 61 73 73 42 79 74 65 43 6F 64 65 3B 01 00 04 6D
00000090h: 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61
000000a0h: 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 61
000000b0h: 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E
000000c0h: 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F 75 72
000000d0h: 63 65 46 69 6C 65 01 00 15 4A 76 6D 43 6C 61 73
000000e0h: 73 42 79 74 65 43 6F 64 65 2E 6A 61 76 61 0C 00
000000f0h: 07 00 08 07 00 1C 0C 00 1D 00 1E 01 00 17 48 65
00000100h: 6C 6C 6F 20 4A 56 4D 20 43 6C 61 73 73 42 79 74
00000110h: 65 43 6F 64 65 07 00 1F 0C 00 20 00 21 01 00 21
00000120h: 63 6F 6D 2F 74 69 67 65 72 6B 69 6E 2F 6A 76 6D
00000130h: 2F 4A 76 6D 43 6C 61 73 73 42 79 74 65 43 6F 64
00000140h: 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62
00000150h: 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67
00000160h: 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15
00000170h: 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74
00000180h: 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69 6F 2F
00000190h: 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72
000001a0h: 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C
000001b0h: 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00 21 00
000001c0h: 05 00 06 00 00 00 00 00 02 00 01 00 07 00 08 00
000001d0h: 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A
000001e0h: B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01
000001f0h: 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05
00000200h: 00 0C 00 0D 00 00 00 09 00 0E 00 0F 00 01 00 09
00000210h: 00 00 00 37 00 02 00 01 00 00 00 09 B2 00 02 12
00000220h: 03 B6 00 04 B1 00 00 00 02 00 0A 00 00 00 0A 00
00000230h: 02 00 00 00 0D 00 08 00 0E 00 0B 00 00 00 0C 00
00000240h: 01 00 00 00 09 00 10 00 11 00 00 00 01 00 12 00
00000250h: 00 00 02 00 13

Class二进制文件基础信息

00000000h: CA FE BA BE 00 00 00 34 00 22 0A 00 06 00 14 09

CA FE BA BE:magic;标识Class文件。
00 00:次要版本。
00 34:主要版本;转换十进制:52,对应 JDK 8版本。

常量池信息

00 22:常量池个数;转换十进制:34,代表(34 - 1)个常量。

常量 1

0A:常量池标签;转换成十进制:10,代表方法引用。
00 06:方法信息:转换成十进制:6,根据 CONSTANT_Methodref_info,这两个字节代表 Class 在常量池中的下标。
00 14:方法信息:转换成十进制:20,根据 CONSTANT_Methodref_info,这两个字节代表方法名称和类型在常量池中的下标。

常量 2

09:常量池标签;转换成十进制:9,代表字段引用。

00000010h: 00 15 00 16 08 00 17 0A 00 18 00 19 07 00 1A 07

00 15:字段信息:转换成十进制:21,根据 CONSTANT_Fieldref_info,这两个字节代表 Class 在常量池中的下标。
00 16:字段信息:转换成十进制:22,根据 CONSTANT_Fieldref_info,这两个字节代表字段名称和类型在常量池中的下标。

常量 3

08:常量池标签;转换成十进制:8,代表字符串。
00 17:字符串信息;转换成十进制:23,根据 CONSTANT_String_info,这两个字节代表字符串在常量池中的下标。

常量 4

0A:常量池标签;转换成十进制:10,代表方法引用。
00 18:方法信息:转换成十进制:24,根据 CONSTANT_Methodref_info,这两个字节代表 Class 在常量池中的下标。
00 19:方法信息:转换成十进制:25,根据 CONSTANT_Methodref_info,这两个字节代表方法名称和类型在常量池中的下标。

常量 5

07:常量池标签;转换成十进制:7,代表 Class。
00 1A:Class 信息:转换成十进制:26,根据 CONSTANT_Class_info,这两个字节代表 Class名称在常量池中的下标。

常量 6

07:常量池标签;转换成十进制:7,代表 Class。

00000020h: 00 1B 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29

00 1B:Class 信息:转换成十进制:27,根据 CONSTANT_Class_info,这两个字节代表 Class 名称在常量池中的下标。

常量 7

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 06:Utf8 字符串信息;转换成十进制:6,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。
3C 69 6E 69 74 3E:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:60 105 110 105 116 62
按照 Unicode 对照表得到字符:<init>

常量 8

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 03:Utf8 字符串信息;转换成十进制:3,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E

28 29 56:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:40 41 86
按照 Unicode 对照表得到字符:()V -> 没有参数的方法

常量 9

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 04:Utf8 字符串信息;转换成十进制:4,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。
43 6F 64 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:67 111 100 101
按照 Unicode 对照表得到字符:Code

常量 10

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 0F:Utf8 字符串信息;转换成十进制:15,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63

4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:76 105 110 101 78 117 109 98 101 114 84 97 98 108 101
按照 Unicode 对照表得到字符:LineNumberTable

常量 11

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 12:Utf8 字符串信息;转换成十进制:18,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000050h: 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01

4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101
按照 Unicode 对照表得到字符:LocalVariableTable

常量 12

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。

00000060h: 00 04 74 68 69 73 01 00 23 4C 63 6F 6D 2F 74 69

00 04:Utf8 字符串信息;转换成十进制:4,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。
74 68 69 73:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:116 104 105 115
按照 Unicode 对照表得到字符:this

常量 13

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 23:Utf8 字符串信息;转换成十进制:35,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000070h: 67 65 72 6B 69 6E 2F 6A 76 6D 2F 4A 76 6D 43 6C
00000080h: 61 73 73 42 79 74 65 43 6F 64 65 3B 01 00 04 6D

4C 63 6F 6D 2F 74 69 67 65 72 6B 69 6E 2F 6A 76 6D 2F 4A 76 6D 43 6C 61 73 73 42 79 74 65 43 6F 64 65 3B:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:76 99 111 109 47 116 105 103 101 114 107 105 110 47 106 118 109 47 74 118 109 67 108 97 115 115 66 121 116 101 67 111 100 101 59
按照 Unicode 对照表得到字符:Lcom/tigerkin/jvm/JvmClassByteCode; -> Class 实例

常量 14

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 04:Utf8 字符串信息;转换成十进制:4,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000090h: 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61

6D 61 69 6E:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:109 97 105 110
按照 Unicode 对照表得到字符:main

常量 15

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 16:Utf8 字符串信息;转换成十进制:22,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000000a0h: 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 61

28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:40 91 76 106 97 118 97 47 108 97 110 103 47 83 116 114 105 110 103 59 41 86
按照 Unicode 对照表得到字符:([Ljava/lang/String;)V -> 带参数的方法,参数为字符串数组

常量 16

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 04:Utf8 字符串信息;转换成十进制:4,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000000b0h: 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E

61 72 67 73:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:97 114 103 115
按照 Unicode 对照表得到字符:args

常量 17

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 13:Utf8 字符串信息;转换成十进制:19,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000000c0h: 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F 75 72

5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:91 76 106 97 118 97 47 108 97 110 103 47 83 116 114 105 110 103 59
按照 Unicode 对照表得到字符:[Ljava/lang/String; -> 字符串数组

常量 18

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 0A:Utf8 字符串信息;转换成十进制:10,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000000d0h: 63 65 46 69 6C 65 01 00 15 4A 76 6D 43 6C 61 73

53 6F 75 72 63 65 46 69 6C 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:83 111 117 114 99 101 70 105 108 101
按照 Unicode 对照表得到字符:SourceFile

常量 19

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 15:Utf8 字符串信息;转换成十进制:21,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000000e0h: 73 42 79 74 65 43 6F 64 65 2E 6A 61 76 61 0C 00

4A 76 6D 43 6C 61 73 73 42 79 74 65 43 6F 64 65 2E 6A 61 76 61:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:74 118 109 67 108 97 115 115 66 121 116 101 67 111 100 101 46 106 97 118 97
按照 Unicode 对照表得到字符:JvmClassByteCode.java

常量 20

0C:常量池标签;转换成十进制:12,代表名称和类型。

000000f0h: 07 00 08 07 00 1C 0C 00 1D 00 1E 01 00 17 48 65

00 07:名称和类型信息;转换成十进制:7,根据 CONSTANT_NameAndType_info,这两个字节代表名称在常量池中的下标。
00 08:名称和类型信息;转换成十进制:8,根据 CONSTANT_NameAndType_info,这两个字节代表描述符号在常量池中的下标。

常量 21

07:常量池标签;转换成十进制:7,代表 Class。
00 1C:Class 信息;转换成十进制:28,根据 CONSTANT_Class_info,这两个字节代表 Class 名称在常量池中的下标。

常量 22

0C:常量池标签;转换成十进制:12,代表名称和类型。
00 1D:名称和类型信息;转换成十进制:29,根据 CONSTANT_NameAndType_info,这两个字节代表名称在常量池中的下标。
00 1E:名称和类型信息;转换成十进制:30,根据 CONSTANT_NameAndType_info,这两个字节代表描述符号在常量池中的下标。

常量 23

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 17:Utf8 字符串信息;转换成十进制:23,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000100h: 6C 6C 6F 20 4A 56 4D 20 43 6C 61 73 73 42 79 74
00000110h: 65 43 6F 64 65 07 00 1F 0C 00 20 00 21 01 00 21

48 65 6C 6C 6F 20 4A 56 4D 20 43 6C 61 73 73 42 79 74 65 43 6F 64 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:72 101 108 108 111 32 74 86 77 32 67 108 97 115 115 66 121 116 101 67 111 100 101
按照 Unicode 对照表得到字符:Hello JVM ClassByteCode

常量 24

07:常量池标签;转换成十进制:7,代表 Class。
00 1F:Class 信息;转换成十进制:31,根据 CONSTANT_Class_info,这两个字节代表 Class 名称在常量池中的下标。

常量 25

0C:常量池标签;转换成十进制:12,代表名称和类型。
00 20:名称和类型信息;转换成十进制:32,根据 CONSTANT_NameAndType_info,这两个字节代表名称在常量池中的下标。
00 21:名称和类型信息;转换成十进制:33,根据 CONSTANT_NameAndType_info,这两个字节代表描述符号在常量池中的下标。

常量 26

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 21:Utf8 字符串信息;转换成十进制:33,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000120h: 63 6F 6D 2F 74 69 67 65 72 6B 69 6E 2F 6A 76 6D
00000130h: 2F 4A 76 6D 43 6C 61 73 73 42 79 74 65 43 6F 64
00000140h: 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62

63 6F 6D 2F 74 69 67 65 72 6B 69 6E 2F 6A 76 6D 2F 4A 76 6D 43 6C 61 73 73 42 79 74 65 43 6F 64 65:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:99 111 109 47 116 105 103 101 114 107 105 110 47 106 118 109 47 74 118 109 67 108 97 115 115 66 121 116 101 67 111 100 101
按照 Unicode 对照表得到字符:com/tigerkin/jvm/JvmClassByteCode

常量 27

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 10:Utf8 字符串信息;转换成十进制:16,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000150h: 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67

6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116
按照 Unicode 对照表得到字符:java/lang/Object

常量 28

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 10:Utf8 字符串信息;转换成十进制:16,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000160h: 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15

6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:106 97 118 97 47 108 97 110 103 47 83 121 115 116 101 109
按照 Unicode 对照表得到字符:java/lang/System

常量 29

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 03:Utf8 字符串信息;转换成十进制:3,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。
6F 75 74:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:111 117 116
按照 Unicode 对照表得到字符:out

常量 30

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 15:Utf8 字符串信息;转换成十进制:21,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000170h: 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74
00000180h: 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69 6F 2F

4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:76 106 97 118 97 47 105 111 47 80 114 105 110 116 83 116 114 101 97 109 59
按照 Unicode 对照表得到字符:Ljava/io/PrintStream; -> Class 实例

常量 31

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 13:Utf8 字符串信息;转换成十进制:19,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

00000190h: 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72

6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:106 97 118 97 47 105 111 47 80 114 105 110 116 83 116 114 101 97 109
按照 Unicode 对照表得到字符:java/io/PrintStream

常量 32

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 07:Utf8 字符串信息;转换成十进制:7,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000001a0h: 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C

70 72 69 6E 74 6C 6E:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:112 114 105 110 116 108 110
按照 Unicode 对照表得到字符:println

常量 33

01:常量池标签;转换成十进制:1,代表 Utf8 字符串。
00 15:Utf8 字符串信息;转换成十进制:21,根据 CONSTANT_Utf8_info,这两个字节代表 Utf8 字符串的长度。

000001b0h: 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00 21 00

28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56:Utf8 字符串信息;根据 Utf8 字符串的长度得到 Utf8 字符串的字节码内容。

转换成十进制:40 76 106 97 118 97 47 108 97 110 103 47 83 116 114 105 110 103 59 41 86
按照 Unicode 对照表得到字符:(Ljava/lang/String;)V -> 带参数的方法,参数为字符串

类信息

00 21:Class 访问修饰符;根据类访问修饰符对照表得到:ACC_PUBLIC、ACC_SUPER。

000001c0h: 05 00 06 00 00 00 00 00 02 00 01 00 07 00 08 00

00 05:当前类信息;转换成十进制:5,代表当前类在常量池中的下标。

00 06:父类信息;转换成十进制:5,代表父类在常量池中的下标。

接口信息

00 00:接口数量;转换成十进制:0,代表没有实现接口。

字段(成员变量)信息

00 00:字段数量;转换成十进制:0,代表有没有字段。

方法信息

00 02:方法数量;转换成十进制:2,代表有两个方法。

方法 1

00 01:方法信息;根据字段访问修饰符对照表得到:ACC_PUBLIC。

00 07:方法信息;转换成十进制:7,代表方法名称在常量中的下标。

00 08:方法信息;转换成十进制:8,代表方法描述符号在常量中的下标。

000001d0h: 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A

00 01:方法信息;转换成十进制:1,代表属性数量。

属性(局部变量) 1

00 09:属性信息;转换成十进制:9,代表属性名称在常量池中的下标。-> Code

00 00 00 2F:Code_attribute 信息;转换成十进制:47,代表属性长度。

00 01:Code_attribute 信息;转换成十进制:1,代表 max_stack 最大栈数量。

00 01:Code_attribute 信息;转换成十进制:1,代表 max_locals 局部变量表长度。

00 00 00 05:Code_attribute 信息;转换成十进制:5,代表字节码的长度。

000001e0h: B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01

2A B7 00 01 B1:根据字节码的长度得到字节码内容。

00 00:Code_attribute 信息;转换成十进制:0,代表异常表长度。

00 02:Code_attribute 信息;转换成十进制:2,代表子属性数量。

局部变量 1 -> 子属性 1 -> 行号表

00 0A:子属性信息;转换成十进制:10,代表属性名称在常量池中的下标。-> LineNumberTable

00 00 00 06:LineNumberTable_attribute 子属性信息;转换成十进制:6,代表 LineNumberTable_attribute 长度。

00 01:LineNumberTable_attribute 子属性信息;转换成十进制:1,代表 line_number_table_length。

line_number_table 1

000001f0h: 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05

00 00:line_number_table 信息;转换成十进制:0,代表 start_pc。

00 0B:line_number_table 信息;转换成十进制:11,代表 line_number。

局部变量 1 -> 子属性 2 -> 局部变量表

00 0B:子属性信息;转换成十进制:11,代表属性名称在常量池中的下标。-> LocalVariableTable

00 00 00 0C:LocalVariableTable_attribute 子属性信息;转换成十进制:12,代表 LocalVariableTable_attribute 长度。

00 01:LocalVariableTable_attribute 子属性信息;转换成十进制:1,代表 LocalVariableTable_attribute local_variable_table_length。

local_variable_table 1

00 00:local_variable_table 信息;转换成十进制:0,代表 start_pc。

00 05:local_variable_table 信息;转换成十进制:5,代表 length。

00000200h: 00 0C 00 0D 00 00 00 09 00 0E 00 0F 00 01 00 09

00 0C:local_variable_table 信息;转换成十进制:12,代表 name_index。

00 0D:local_variable_table 信息;转换成十进制:13,代表 descriptor_index。

00 00:local_variable_table 信息;转换成十进制:0,代表 index。

方法 2

00 09:方法信息;根据字段访问修饰符对照表得到:ACC_PUBLIC、ACC_STATIC。

00 0E:方法信息;转换成十进制:14,代表方法名称在常量中的下标。

00 0F:方法信息;转换成十进制:15,代表方法描述符号在常量中的下标。

00 01:方法信息;转换成十进制:1,代表属性数量。

属性(局部变量)1

00 09:属性信息;转换成十进制:9,代表属性名称在常量池中的下标。-> Code

00000210h: 00 00 00 37 00 02 00 01 00 00 00 09 B2 00 02 12

00 00 00 37:Code_attribute 信息;转换成十进制:55,代表属性长度。

00 02:Code_attribute 信息;转换成十进制:2,代表 max_stack 最大栈数量。

00 01:Code_attribute 信息;转换成十进制:1,代表 max_locals 局部变量表长度。

00 00 00 09:Code_attribute 信息;转换成十进制:9,代表字节码的长度。

00000220h: 03 B6 00 04 B1 00 00 00 02 00 0A 00 00 00 0A 00

B2 00 02 12 03 B6 00 04 B1:根据字节码的长度得到字节码内容。

00 00:Code_attribute 信息;转换成十进制:0,代表异常表长度。

00 02:Code_attribute 信息;转换成十进制:2,代表子属性数量。

局部变量 1 -> 子属性 1 -> 行号表

00 0A:子属性信息;转换成十进制:10,代表属性名称在常量池中的下标。-> LineNumberTable

00 00 00 0A:LineNumberTable_attribute 子属性信息;转换成十进制:10,代表 LineNumberTable_attribute 长度。

00000230h: 02 00 00 00 0D 00 08 00 0E 00 0B 00 00 00 0C 00

00 02:LineNumberTable_attribute 子属性信息;转换成十进制:2,代表 line_number_table_length。

line_number_table 1

00 00:line_number_table 信息;转换成十进制:0,代表 start_pc。

00 0D:line_number_table 信息;转换成十进制:13,代表 line_number。

line_number_table 2

00 08:line_number_table 信息;转换成十进制:8,代表 start_pc。

00 0E:line_number_table 信息;转换成十进制:14,代表 line_number。

局部变量 1 -> 子属性 2 -> 局部变量表

00 0B:子属性信息;转换成十进制:11,代表属性名称在常量池中的下标。-> LocalVariableTable

00 00 00 0C:LocalVariableTable_attribute 子属性信息;转换成十进制:12,代表 LocalVariableTable_attribute 长度。

00000240h: 01 00 00 00 09 00 10 00 11 00 00 00 01 00 12 00

00 01:LocalVariableTable_attribute 子属性信息;转换成十进制:1,代表 LocalVariableTable_attribute local_variable_table_length。

local_variable_table 1

00 00:local_variable_table 信息;转换成十进制:0,代表 start_pc。

00 09:local_variable_table 信息;转换成十进制:9,代表 length。

00 10:local_variable_table 信息;转换成十进制:16,代表 name_index。

00 11:local_variable_table 信息;转换成十进制:17,代表 descriptor_index。

00 00:local_variable_table 信息;转换成十进制:0,代表 index。

Class 属性信息

00 01:Class 属性信息;转换成十进制:1,代表属性数量。

Class 属性 1

00 12:Class 属性信息;转换成十进制:18,代表属性名称在常量池中的下标。-> SourceFile_attribute

00000250h: 00 00 02 00 13

00 00 00 02:SourceFile_attribute 信息;转换成十进制:2,代表 SourceFile_attribute 长度。

00 13:SourceFile_attribute 信息;转换成十进制:19,代表源文件在常量池中的下标。

Class文件构成

ClassFile {
    u4             magic; // 魔法:标识Class文件
    u2             minor_version; // 次要版本
    u2             major_version; // 主要版本
    u2             constant_pool_count; // 常量池的个数
    cp_info        constant_pool[constant_pool_count-1]; // 常量池信息
    u2             access_flags; // Class访问修饰
    u2             this_class; // 当前类信息
    u2             super_class; // 父类信息
    u2             interfaces_count; // 接口数量
    u2             interfaces[interfaces_count]; // 接口信息
    u2             fields_count; // 字段数量
    field_info     fields[fields_count]; 字段信息
    u2             methods_count; // 方法数量
    method_info    methods[methods_count]; // 方法信息
    u2             attributes_count; // 属性数量
    attribute_info attributes[attributes_count]; // 属性信息
}

cp_info 常量池信息

cp_info {
    u1 tag; // 标签
    u1 info[];
}
CONSTANT_Class_info
CONSTANT_Class_info {
    u1 tag; // 标签
    u2 name_index; // 名称在常量池中下标
}
CONSTANT_Fieldref_info
CONSTANT_Fieldref_info {
    u1 tag; // 标签
    u2 class_index;
    u2 name_and_type_index;
}
CONSTANT_Methodref_info
CONSTANT_Methodref_info {
    u1 tag; // 标签
    u2 class_index;
    u2 name_and_type_index;
}
CONSTANT_InterfaceMethodref_info
CONSTANT_InterfaceMethodref_info {
    u1 tag; // 标签
    u2 class_index;
    u2 name_and_type_index;
}
CONSTANT_String_info
CONSTANT_String_info {
    u1 tag;
    u2 string_index;
}
CONSTANT_Integer_info
CONSTANT_Integer_info {
    u1 tag;
    u4 bytes;
}
CONSTANT_Float_info
CONSTANT_Float_info {
    u1 tag;
    u4 bytes;
}
CONSTANT_Long_info
CONSTANT_Long_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
CONSTANT_Double_info
CONSTANT_Double_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}
CONSTANT_NameAndType_info
CONSTANT_NameAndType_info {
    u1 tag;
    u2 name_index;
    u2 descriptor_index;
}
CONSTANT_Utf8_info
CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}
CONSTANT_MethodHandle_info
CONSTANT_MethodHandle_info {
    u1 tag;
    u1 reference_kind;
    u2 reference_index;
}
CONSTANT_MethodType_info
CONSTANT_MethodType_info {
    u1 tag;
    u2 descriptor_index;
}
CONSTANT_InvokeDynamic_info
CONSTANT_InvokeDynamic_info {
    u1 tag;
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
}

field_info

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

method_info

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

attribute_info

attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}
Code_attribute
Code_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 max_stack;
    u2 max_locals;
    u4 code_length;
    u1 code[code_length];
    u2 exception_table_length;
    {   u2 start_pc;
        u2 end_pc;
        u2 handler_pc;
        u2 catch_type;
    } exception_table[exception_table_length];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}
LineNumberTable_attribute
LineNumberTable_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 line_number_table_length;
    {   u2 start_pc;
        u2 line_number;	
    } line_number_table[line_number_table_length];
}
LocalVariableTable_attribute
LocalVariableTable_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 local_variable_table_length;
    {   u2 start_pc;
        u2 length;
        u2 name_index;
        u2 descriptor_index;
        u2 index;
    } local_variable_table[local_variable_table_length];
}
SourceFile_attribute
SourceFile_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 sourcefile_index;
}

JDK版本号对应

JDK版本版本号
751
852
953
1054
1155
1256
1357
1458
1559
1660

常量池标签

常量类型描述
CONSTANT_Class7Class类
CONSTANT_Fieldref9字段引用
CONSTANT_Methodref10方法引用
CONSTANT_InterfaceMethodref11接口方法引用
CONSTANT_String8字符串
CONSTANT_Integer3整型数字
CONSTANT_Float4单精度浮点型数字
CONSTANT_Long5长整型数字
CONSTANT_Double6双精度浮点型数字
CONSTANT_NameAndType12字段或者方法
CONSTANT_Utf81UTF8常量字符串
CONSTANT_MethodHandle15方法处理
CONSTANT_MethodType16方法类型
CONSTANT_InvokeDynamic18动态调用

类的访问修饰符

标志名称价值解释
ACC_PUBLIC0x0001声明 public;可以从其包外部访问。
ACC_FINAL0x0010声明 final;不允许子类。
ACC_SUPER0x0020当被 invokespecial 指令调用时,对父类方法进行特殊处理。
ACC_INTERFACE0x0200声明 interface 接口,不是类。
ACC_ABSTRACT0x0400声明 abstract 抽象类;不能被实例化。
ACC_SYNTHETIC0x1000声明 synthetic;源代码中不存在。
ACC_ANNOTATION0x2000声明 annotation 注解类。
ACC_ENUM0x4000声明 enum 枚举类。

字段的访问修饰符

标志名称价值解释
ACC_PUBLIC0x0001声明 public;可以从其包外部访问。
ACC_PRIVATE0x0002声明 private;只能在当前类使用。
ACC_PROTECTED0x0004声明 protected;可以在子类中访问。
ACC_STATIC0x0008声明 static。
ACC_FINAL0x0010声明 final;从不在对象构造后直接赋值。
ACC_VOLATILE0x0040声明 volatile;不能被缓存。
ACC_TRANSIENT0x0080声明 transient;不能由持久对象管理器写入或读取。
ACC_SYNTHETIC0x1000声明 synthetic;源代码中不存在。
ACC_ENUM0x4000声明 enum 枚举类。

方法的访问修饰符

标志名称价值解释
ACC_PUBLIC0x0001声明 public;可以从其包外部访问。
ACC_PRIVATE0x0002声明 private;只能在当前类使用。
ACC_PROTECTED0x0004声明 protected;可以在子类中访问。
ACC_STATIC0x0008声明 static。
ACC_FINAL0x0010声明 final;不能被重写。
ACC_SYNCHRONIZED0x0020声明 synchronized;调用由监视器使用包装。
ACC_BRIDGE0x0040一个桥接方法,由编译器生成。
ACC_VARARGS0x0080使用可变数量的参数声明。
ACC_NATIVE0x0100声明 native;本地方法,用 Java 以外的语言实现。
ACC_ABSTRACT0x0400声明 abstract;没有提供实现。
ACC_STRICT0x0800声明 strictfp;浮点模式是FP-strict模式。
ACC_SYNTHETIC0x1000声明 synthetic;源代码中不存在。

字段描述符

字段类型术语类型解释
Bbyte字节
Cchar基本多语言平面中的Unicode字符编码,用UTF-16编码
Ddouble双精度浮点数值
Ffloat单精度浮点数值
Iint整形数字
Jlong长整型数字
L ClassName ;referenceClassName 实例
Sshort短整型数字
Zbooleantrue 或者 false
[reference一维数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值