JVM-Class文件结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cdw8131197/article/details/67675655

Class文件结构

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部都是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上的空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:无符号数和表。

无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值,或者按照UTF-8编码构成字符串值。

是由多个无符号数或者其它表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。 它由下表所示的数据项构成。

这里写图片描述

magic:魔数,作用确定这个文件是否是能被虚拟机接受的class文件;若是能被jvm接受的class文件,它的值为:0xCAFEBABE。它的类型是u4,表示4个字节的无符号数;
如下所示是一个class的十六进制表示:
这里写图片描述
minor_version 和 major_version:分别表示版本号。jdk的版本不同,他们的值是不同的。下图是表示不同jdk版本下的值;
这里写图片描述

下图示例中,class是使用jdk1.8编译的,版本号值为
00 00 (minor_version) 00 34(major_version)

这里写图片描述

constant_pool_count 和constant_pool:
常量池是Class文件结构中与其它项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在文件中第一个出现的表类型数据项目。由于常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。从1开始计数。第0项腾出来满足后面某些指向常量池的索引值的数据在特定情况下需要表达”不引用任何一个常量池项目”的意思,这种情况就可以把索引值置为0来表示。但尽管constant_pool列表中没有索引值为0的入口,缺失的这一入口也被constant_pool_count计数在内。例如,当constant_pool中有14项,constant_poo_count的值为15。Class文件结构中只有常量池的容量计数是从1开始的,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都是从0开始的。

constant_pool cp_info:
这里写图片描述

1、CONSTANT_Utf8
-tag 1 (上述表中的tag值)
-length u2 (长度)
-bytes[length] (字节数组)

2、CONSTANT_Integer
-tag 3
-byte u4
java语句public static final int sid=99;
可表示成
这里写图片描述

3、CONSTANT_String
-tag 8
-string_index u2 (指向utf8的索引)
如public static final String sname=”geym”;

这里写图片描述
字符串的值指向了cp_info#16,而#16表示的是uft-8常量。

4、CONSTANT_NameAndType
-tag 12
-name_index u2 (名字,指向utf8的索引)
-descriptor_index u2 (描述符类型,指向utf8的索引)
这里写图片描述
<init>表示构造函数
()V表示无参且无返回值

5、CONSTANT_Class
-tag 7
-name_index u2 (class名字,指向utf8索引)
这里写图片描述

6、CONSTANT_Fieldref ,CONSTANT_Methodref ,
CONSTANT_InterfaceMethodref
-tag 9 ,10, 11
-class_index u2 (指向CONSTANT_Class)
-name_and_type_index u2 (指向CONSTANT_NameAndType)
这里写图片描述

access flag u2:类的标示符;

这里写图片描述

this_class:本类,指向CONSTANT_Class的索引;

super_class:父类,指向CONSTANT_Class的索引;

interface_count:接口数量;

**interfaces:**interface_count 个 interface,每个interface是指向CONSTANT_Class的索引;

field_count:字段数量;

fields: field_count个field_info;

field_info表:
1、access_flags u2
这里写图片描述
2、name_index u2
常量池引用 ,表示字段的名字
3、descriptor_index u2
表示字段的类型如下:
B byte
C char
D double
F float
I int
J long
S short
Z boolean
V void
L 对象 例如:Ljava/lang/Object;
[数组
[[二维数组 例如:[Ljava/lang/String; = String[][]
4、attributes_count u2
5、attribute_info attributes[attributes_count];

methods_count: 方法数量
methods: methods_count个method_info
method_info:
1、access_flags u2
这里写图片描述
2、name_index u2
方法名字,常量池UTF-8索引
3、descriptor_index u2
类型同field_info的descriptor_index u2 ,用于表达方法的参数和返回值
例如:
void inc() —表示成: ()V
void setId(int) —表示成: (I)V
int indexOf(char[],int ) —表示成: ([CI)I
4、attributes_count u2
5、attribute_info attributes[attributes_count];

attribute
这里写图片描述
1、Deprecated
attribute_name_index u2
attribute_length u4
attribute_name_index:指向包含Deprecated的UTF-8常量
attribute_length:0
2、ConstantValue
attribute_name_index u2
attribute_length u4
constantvalue_index u2
attribute_name_index:包含ConstantantValue字面量的UTF-8索引
attribute_length:2
constantvalue_index:常量值,指向常量池,可以是UTF-8,Float, Double 等
3、Code
这里写图片描述
4、LineNumberTable - Code属性的属性
这里写图片描述
5、LocalVariableTable - Code属性的属性
这里写图片描述
6、Exceptions属性
和Code属性平级,表示方法抛出的异常(不是try catch部分,而是 throws部分)结构
attribute_name_index u2
attribute_length u4
number_of_exceptions u2
exception_index_table[number_of_exceptions] u2
指向Constant_Class的索引

猜你喜欢

转载自blog.csdn.net/cdw8131197/article/details/67675655