class文件解析示例

class文件的格式等理论概念网上很多,不再赘述,下面是针对一个class文件实例进行”翻译“。

源文件

package com.sss.jvm.unclassified;
public class SimpleUser {
    public static final int TYPE = 1;

    private int id;
    private String name;

    public int getId(){
        return id;
    }

    public void setId(int id) throws IllegalStateException{
        try {
            this.id = id;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

class文件

cafe babe 0000 0034 002f 0a00 0700 2609
0006 0027 0700 280a 0003 0029 0900 0600
2a07 002b 0700 2c01 0004 5459 5045 0100
0149 0100 0d43 6f6e 7374 616e 7456 616c
7565 0300 0000 0101 0002 6964 0100 046e
616d 6501 0012 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 0100 063c 696e 6974
3e01 0003 2829 5601 0004 436f 6465 0100
0f4c 696e 654e 756d 6265 7254 6162 6c65
0100 124c 6f63 616c 5661 7269 6162 6c65
5461 626c 6501 0004 7468 6973 0100 254c
636f 6d2f 7373 732f 6a76 6d2f 756e 636c
6173 7369 6669 6564 2f53 696d 706c 6555
7365 723b 0100 0567 6574 4964 0100 0328
2949 0100 0573 6574 4964 0100 0428 4929
5601 0001 6501 0015 4c6a 6176 612f 6c61
6e67 2f45 7863 6570 7469 6f6e 3b01 000d
5374 6163 6b4d 6170 5461 626c 6507 0028
0100 0a45 7863 6570 7469 6f6e 7307 002d
0100 0767 6574 4e61 6d65 0100 1428 294c
6a61 7661 2f6c 616e 672f 5374 7269 6e67
3b01 0007 7365 744e 616d 6501 0015 284c
6a61 7661 2f6c 616e 672f 5374 7269 6e67
3b29 5601 000a 536f 7572 6365 4669 6c65
0100 0f53 696d 706c 6555 7365 722e 6a61
7661 0c00 0f00 100c 000c 0009 0100 136a
6176 612f 6c61 6e67 2f45 7863 6570 7469
6f6e 0c00 2e00 100c 000d 000e 0100 2363
6f6d 2f73 7373 2f6a 766d 2f75 6e63 6c61
7373 6966 6965 642f 5369 6d70 6c65 5573
6572 0100 106a 6176 612f 6c61 6e67 2f4f
626a 6563 7401 001f 6a61 7661 2f6c 616e
672f 496c 6c65 6761 6c53 7461 7465 4578
6365 7074 696f 6e01 000f 7072 696e 7453
7461 636b 5472 6163 6500 2100 0600 0700
0000 0300 1900 0800 0900 0100 0a00 0000
0200 0b00 0200 0c00 0900 0000 0200 0d00
0e00 0000 0500 0100 0f00 1000 0100 1100
0000 2f00 0100 0100 0000 052a b700 01b1
0000 0002 0012 0000 0006 0001 0000 0007
0013 0000 000c 0001 0000 0005 0014 0015
0000 0001 0016 0017 0001 0011 0000 002f
0001 0001 0000 0005 2ab4 0002 ac00 0000
0200 1200 0000 0600 0100 0000 0e00 1300
0000 0c00 0100 0000 0500 1400 1500 0000
0100 1800 1900 0200 1100 0000 7100 0200
0300 0000 0e2a 1bb5 0002 a700 084d 2cb6
0004 b100 0100 0000 0500 0800 0300 0300
1200 0000 1600 0500 0000 1300 0500 1600
0800 1400 0900 1500 0d00 1700 1300 0000
2000 0300 0900 0400 1a00 1b00 0200 0000
0e00 1400 1500 0000 0000 0e00 0c00 0900
0100 1c00 0000 0700 0248 0700 1d04 001e
0000 0004 0001 001f 0001 0020 0021 0001
0011 0000 002f 0001 0001 0000 0005 2ab4
0005 b000 0000 0200 1200 0000 0600 0100
0000 1a00 1300 0000 0c00 0100 0000 0500
1400 1500 0000 0100 2200 2300 0100 1100
0000 3e00 0200 0200 0000 062a 2bb5 0005
b100 0000 0200 1200 0000 0a00 0200 0000
1e00 0500 1f00 1300 0000 1600 0200 0000
0600 1400 1500 0000 0000 0600 0d00 0e00
0100 0100 2400 0000 0200 25

逐行解析

常量id待分析的十六进制转换十进制/可视化翻译
cafe babe魔数,固定值,“咖啡宝贝”
0000 00340 52低版本0,高版本52,也就是jdk1.8
002f47常量值有47-1=46个元素,第0个空缺
#10a10CONSTANT_Methodref_info
00 077指向CONSTANT_Class_info的索引
00 2638指向CONSTANT_NameAndType_info的索引
#2099CONSTANT_Fieldref_info
00 066指向CONSTANT_Class_info的索引
00 2739指向CONSTANT_NameAndType_info的索引
#3077CONSTANT_Class_info
00 2840指向#40
#40a10CONSTANT_Methodref_info
00 033指向CONSTANT_Class_info的索引
00 2941指向CONSTANT_NameAndType_info的索引
#5099CONSTANT_Fieldref_info
00 066指向CONSTANT_Class_info的索引
00 2a42指向CONSTANT_NameAndType_info的索引
#6077CONSTANT_Class_info
00 2b43指向常量43的索引
#7077CONSTANT_Class_info
00 2c44指向#44
#8011CONSTANT_Utf8_info
00 044UTF8编码的字符串,长度为4
54 59 50 45TYPETYPE
#9011CONSTANT_Utf8_info
00 011UTF8编码的字符串,长度为1
49II
#10011CONSTANT_Utf8_info
00 0d13UTF8编码的字符串,长度为13
43 6f 6e 73 74 61 6e 74 56 61 6c 75 65ConstantValueConstantValue
#11033CONSTANT_Intege_info
00 00 00 0111
#12011CONSTANT_Utf8_info
00 022UTF8编码的字符串,长度为2
69 64idid
#13011CONSTANT_Utf8_info
00 044UTF8编码的字符串,长度为4
6e 616d 65namename
#14011CONSTANT_Utf8_info
00 1218UTF8编码的字符串,长度为12
4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673bLjava/lang/String;Ljava/lang/String;
#15011CONSTANT_Utf8_info
00 066UTF8编码的字符串,长度为6
3c 696e 6974 3e
#16011CONSTANT_Utf8_info
00 033UTF8编码的字符串,长度为3
2829 56()V()V
#17011CONSTANT_Utf8_info
00044UTF8编码的字符串,长度为4
436f 6465CodeCode
#18011CONSTANT_Utf8_info
00 0f15UTF8编码的字符串,长度为15
4c 696e 654e 756d 6265 7254 6162 6c65LineNumberTableLineNumberTable
#19011CONSTANT_Utf8_info
00 1218UTF8编码的字符串,长度为18
4c 6f63 616c 5661 7269 6162 6c65 5461 626c 65LocalVariableTableLocalVariableTable
#20011CONSTANT_Utf8_info
00 044UTF8编码的字符串,长度为4
7468 6973thisthis
#21011CONSTANT_Utf8_info
00 2537UTF8编码的字符串,长度为37
54c 636f 6d2f 7373 732f 6a76 6d2f 756e 636c 6173 7369 6669 6564 2f53 696d 706c 6555 7365 723bLcom/sss/jvm/unclassified/SimpleUser;Lcom/sss/jvm/unclassified/SimpleUser;
#22011CONSTANT_Utf8_info
00 055UTF8编码的字符串,长度为4
67 6574 4964getIdgetId
#23011CONSTANT_Utf8_info
00 033UTF8编码的字符串,长度为3
28 2949()I()I
#24011CONSTANT_Utf8_info
00 055UTF8编码的字符串,长度为3
73 6574 4964setIdsetId
#25011CONSTANT_Utf8_info
00 044UTF8编码的字符串,长度为4
28 4929 56(I)V(I)V
#26011CONSTANT_Utf8_info
00 011UTF8编码的字符串,长度为1
65ee
#27011CONSTANT_Utf8_info
00 1521UTF8编码的字符串,长度为21
4c6a 6176 612f 6c61 6e67 2f45 7863 6570 7469 6f6e 3bLjava/lang/Exception;Ljava/lang/Exception;
#28011CONSTANT_Utf8_info
00 0d13UTF8编码的字符串,长度为13
5374 6163 6b4d 6170 5461 626c 65StackMapTableStackMapTable
#29077CONSTANT_Class_info
00 2840指向#40
#30011CONSTANT_Utf8_info
00 0a10UTF8编码的字符串,长度为10
45 7863 6570 7469 6f6e 73ExceptionsExceptions
#31077CONSTANT_Class_info
00 2d45指向#45
#32011CONSTANT_Utf8_info
00 077UTF8编码的字符串,长度为7
67 6574 4e61 6d65getNamegetName
#33011CONSTANT_Utf8_info
00 1420UTF8编码的字符串,长度为20
28 294c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b()Ljava/lang/String;()Ljava/lang/String;
#34011CONSTANT_Utf8_info
00 077UTF8编码的字符串,长度为7
7365 744e 616d 65setNamesetName
#35011CONSTANT_Utf8_info
00 1521UTF8编码的字符串,长度为21
284c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b29 56(Ljava/lang/String;)V(Ljava/lang/String;)V
#36011CONSTANT_Utf8_info
00 0a10UTF8编码的字符串,长度为10
536f 7572 6365 4669 6c65SourceFileSourceFile
#37011CONSTANT_Utf8_info
00 0f15UTF8编码的字符串,长度为15
53 696d 706c 6555 7365 722e 6a61 7661SimpleUser.javaSimpleUser.java
#380c12CONSTANT_NameAndType_info
00 0f15指向#15
00 1016指向#16
#390c12CONSTANT_NameAndType_info
00 0c12指向#12
00 089指向#9
#40011CONSTANT_Utf8_info
00 1319UTF8编码的字符串,长度为15
6a 6176 612f 6c61 6e67 2f45 7863 6570 7469 6f6ejava/lang/Exceptionjava/lang/Exception
#410c12CONSTANT_NameAndType_info
00 2e46指向#46
00 1016指向#16
#420c12CONSTANT_NameAndType_info
00 0d13指向#13
00 0e14指向#14
#43011CONSTANT_Utf8_info
00 2335UTF8编码的字符串,长度为35
63 6f6d 2f73 7373 2f6a 766d 2f75 6e63 6c61 7373 6966 6965 642f 5369 6d70 6c65 5573 6572com/sss/jvm/unclassified/SimpleUsercom/sss/jvm/unclassified/SimpleUser
#44011CONSTANT_Utf8_info
00 1016UTF8编码的字符串,长度为16
6a 6176 612f 6c61 6e67 2f4f 626a 6563 74java/lang/Objectjava/lang/Object
#45011CONSTANT_Utf8_info
00 1f31UTF8编码的字符串,长度为31
6a61 7661 2f6c 616e 672f 496c 6c65 6761 6c53 7461 7465 4578 6365 7074 696f 6ejava/lang/IllegalStateExceptionjava/lang/IllegalStateException
#46011CONSTANT_Utf8_info
00 0f15UTF8编码的字符串,长度为15
7072 696e 7453 7461 636b 5472 6163 65printStackTraceprintStackTrace
00 2100 21是0020和0001的并集,表示ACC_PUBLIC和ACC_SUPER类的访问修饰符
00 06指向#6,即com/sss/jvm/unclassified/SimpleUser类名
00 07指向#7,即java/lang/Object父类名
#接口00 00接口数量0接口数量0
#成员变量00 03成员变量3个成员变量3个
成员变量100 19access_flagspublic + final + static
00 08name_indexTYPE
00 09descriptor_indexI (int的缩写)
00 01attributes_count1

javap查看字节码验证

  Last modified 2020-7-26; size 1003 bytes
  MD5 checksum 649990cb1874364be61948448f5976d9
  Compiled from "SimpleUser.java"
public class com.sss.jvm.unclassified.SimpleUser
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#38         // java/lang/Object."<init>":()V
   #2 = Fieldref           #6.#39         // com/sss/jvm/unclassified/SimpleUser.id:I
   #3 = Class              #40            // java/lang/Exception
   #4 = Methodref          #3.#41         // java/lang/Exception.printStackTrace:()V
   #5 = Fieldref           #6.#42         // com/sss/jvm/unclassified/SimpleUser.name:Ljava/lang/String;
   #6 = Class              #43            // com/sss/jvm/unclassified/SimpleUser
   #7 = Class              #44            // java/lang/Object
   #8 = Utf8               TYPE
   #9 = Utf8               I
  #10 = Utf8               ConstantValue
  #11 = Integer            1
  #12 = Utf8               id
  #13 = Utf8               name
  #14 = Utf8               Ljava/lang/String;
  #15 = Utf8               <init>
  #16 = Utf8               ()V
  #17 = Utf8               Code
  #18 = Utf8               LineNumberTable
  #19 = Utf8               LocalVariableTable
  #20 = Utf8               this
  #21 = Utf8               Lcom/sss/jvm/unclassified/SimpleUser;
  #22 = Utf8               getId
  #23 = Utf8               ()I
  #24 = Utf8               setId
  #25 = Utf8               (I)V
  #26 = Utf8               e
  #27 = Utf8               Ljava/lang/Exception;
  #28 = Utf8               StackMapTable
  #29 = Class              #40            // java/lang/Exception
  #30 = Utf8               Exceptions
  #31 = Class              #45            // java/lang/IllegalStateException
  #32 = Utf8               getName
  #33 = Utf8               ()Ljava/lang/String;
  #34 = Utf8               setName
  #35 = Utf8               (Ljava/lang/String;)V
  #36 = Utf8               SourceFile
  #37 = Utf8               SimpleUser.java
  #38 = NameAndType        #15:#16        // "<init>":()V
  #39 = NameAndType        #12:#9         // id:I
  #40 = Utf8               java/lang/Exception
  #41 = NameAndType        #46:#16        // printStackTrace:()V
  #42 = NameAndType        #13:#14        // name:Ljava/lang/String;
  #43 = Utf8               com/sss/jvm/unclassified/SimpleUser
  #44 = Utf8               java/lang/Object
  #45 = Utf8               java/lang/IllegalStateException
  #46 = Utf8               printStackTrace
{
  public static final int TYPE;
    descriptor: I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: int 1

  private int id;
    descriptor: I
    flags: ACC_PRIVATE

  private java.lang.String name;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE

  public com.sss.jvm.unclassified.SimpleUser();
    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 7: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/sss/jvm/unclassified/SimpleUser;

  public int getId();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field id:I
         4: ireturn
      LineNumberTable:
        line 14: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/sss/jvm/unclassified/SimpleUser;

  public void setId(int) throws java.lang.IllegalStateException;
    descriptor: (I)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #2                  // Field id:I
         5: goto          13
         8: astore_2
         9: aload_2
        10: invokevirtual #4                  // Method java/lang/Exception.printStackTrace:()V
        13: return
      Exception table:
         from    to  target type
             0     5     8   Class java/lang/Exception
      LineNumberTable:
        line 19: 0
        line 22: 5
        line 20: 8
        line 21: 9
        line 23: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            9       4     2     e   Ljava/lang/Exception;
            0      14     0  this   Lcom/sss/jvm/unclassified/SimpleUser;
            0      14     1    id   I
      StackMapTable: number_of_entries = 2
        frame_type = 72 /* same_locals_1_stack_item */
          stack = [ class java/lang/Exception ]
        frame_type = 4 /* same */
    Exceptions:
      throws java.lang.IllegalStateException

  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #5                  // Field name:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 26: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/sss/jvm/unclassified/SimpleUser;

  public void setName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #5                  // Field name:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 30: 0
        line 31: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/sss/jvm/unclassified/SimpleUser;
            0       6     1  name   Ljava/lang/String;
}
SourceFile: "SimpleUser.java"

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值