编写一个简单的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虚拟机>>):
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