继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

记一次解析class文件过程

慕村9548890
关注TA
已关注
手记 1281
粉丝 227
获赞 991

编写一个简单的Class文件

public class TestClass {
    private int m;    public int inc(){        return m++;
    }
}

查看编译出来的Class文件二进制:

localhost:baseLearning jjchen$ xxd TestClass.class 00000000: cafe babe 0000 0034 0016 0a00 0400 1209  .......4........00000010: 0003 0013 0700 1407 0015 0100 016d 0100  .............m..00000020: 0149 0100 063c 696e 6974 3e01 0003 2829  .I...<init>...()00000030: 5601 0004 436f 6465 0100 0f4c 696e 654e  V...Code...LineN00000040: 756d 6265 7254 6162 6c65 0100 124c 6f63  umberTable...Loc00000050: 616c 5661 7269 6162 6c65 5461 626c 6501  alVariableTable.00000060: 0004 7468 6973 0100 0b4c 5465 7374 436c  ..this...LTestCl00000070: 6173 733b 0100 0369 6e63 0100 0328 2949  ass;...inc...()I00000080: 0100 0a53 6f75 7263 6546 696c 6501 000e  ...SourceFile...00000090: 5465 7374 436c 6173 732e 6a61 7661 0c00  TestClass.java..000000a0: 0700 080c 0005 0006 0100 0954 6573 7443  ...........TestC000000b0: 6c61 7373 0100 106a 6176 612f 6c61 6e67  lass...java/lang000000c0: 2f4f 626a 6563 7400 2100 0300 0400 0000  /Object.!.......000000d0: 0100 0200 0500 0600 0000 0200 0100 0700  ................000000e0: 0800 0100 0900 0000 2f00 0100 0100 0000  ......../.......000000f0: 052a b700 01b1 0000 0002 000a 0000 0006  .*..............00000100: 0001 0000 0001 000b 0000 000c 0001 0000  ................00000110: 0005 000c 000d 0000 0001 000e 000f 0001  ................00000120: 0009 0000 0036 0004 0001 0000 000c 2a59  .....6........*Y00000130: b400 025a 0460 b500 02ac 0000 0002 000a  ...Z.`..........
00000140: 0000 0006 0001 0000 0004 000b 0000 000c  ................
00000150: 0001 0000 000c 000c 000d 0000 0001 0010  ................
00000160: 0000 0002 0011

Class头

前面4个字节是固定的cafe babe,标识这是一个class文件,接下来的6个字节和java版本相关0000 0034,版本52 对应jdk1.8中的一个版本。

常量区

接下来的0016,代表常量池中有21个常量(从1开始,0保留).常量类型一共有12种,他们的结构都是不一样的,在class文件中紧致排列,十二种类型结构如图(摘自<<深入理解java虚拟机>>):

webp

8.jpg


下面根据上图解析class文件常量区:

1.指向方法的引用(二进制为5个字节:0a 0004 0012),内容有两个(1)指向类描述符CONSTANT_Class_info的索引项(第四项),(2)指向名称及类型描述符CONSTANT_NameAndType的索引项(第18项)。

2.CONSTANT_Fieldref_info 指向类成员变量的引用(二进制为5个字节:09 0003 0013)内容有两个(1)指向所属的类或者接口的对象(2)指向

3.CONSTANT_Class_info (二进制为3个字节:07 0014)对应20号常量区TestClass

4.CONSTANT_Class_info(二进制为3个字节:07 0015)对应21号常量区java/lang/Object

5.UTF-8常量(二进制为变长结构: 1字节+标识长度的2字节+length字节: 01 0001 6d),m

6.UTF-8常量(二进制:01 0001 49), I

7.UTF-8常量(二进制:01 0006 3c69 6e69 743e), <init>

8.UTF-8常量(二进制:01 0003 2829 56), ()V

9.UTF-8常量(二进制:01 0004 436f 6465), Code

10.UTF-8常量(二进制:01 000f 4c69 6e65 4e75 6d62 6572 5461 626c 65),LineNumberTable

11.UTF-8常量(二进制:01 0012 4c6f 6361 6c56 6172 6961 626c 6554 6162 6c65),LocalVariableTable

12.UTF-8常量(二进制:0004 7468 6973),this

13.UTF-8常量(二进制:01 000b 4c54 6573 7443 6c61 7373 3b),LTestClass

14.UTF-8常量(二进制:01 0003 696e 63),inc

15.UTF-8常量(二进制:01 0003 2829 49),()I

16.UTF-8常量(二进制:01 000a 536f 7572 6365 4669 6c65),SourceFile

17.UTF-8常量(二进制:01 000e 5465 7374 436c 6173 732e 6a61 7661),TestClass.java

18.CONSTANT_NameAndType 类型(二进制:0c 0007 0008), 内容有两个,(1)指向字段或方法名常量项的索引,0007:<init> ,(2)指向字段或方法名的描述符常量项索引0008:()V

19.CONSTANT_NameAndType 类型(二进制:0c 0005 0006), (1)m (2)I

...



作者:msrpp
链接:https://www.jianshu.com/p/8f53af3c0bd9


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP