您的位置:首页 > 编程语言 > Java开发

java.class文件结构学习

2017-09-01 10:07 295 查看
1.

u1,u2,u3,u4 表示 1字节,2字节,3字节,4字节

class文件

类型     名称     数量

u4     magic     1

u2     minor_version     1

u2     major_version     1

u2     constant_pool_count     1

cp_info     constant_pool     constant_pool_count - 1

u2     access_flags     1    (access_flags 描述的是当前类(或者接口)的访问修饰符, 如public, private等,还有该类是类,接口还是枚举等)

u2     this_class     1    (当前类的信息,索引class_index ->CONSTANT_Class_info)

u2     super_class     1    (父类的信息,索引class_index ->CONSTANT_Class_info)

u2     interfaces_count     1    (当前类接口数量)

face_info     interfaces     interfaces_count    (每一个接口占u2块,每一块有个索引然后指向CONSTANT_Class_info)

u2     fields_count     1    (当前类定义的字段(变量)的个数,但不包括从父类继承的字段)

field_info     fields     fields_count    (下面有描述)

u2     methods_count     1    (当前类中定义的方法个数,不包括从父类继承的方法)

method_info     methods     methods_count    (对方法的描述)

u2     attribute_count     1        (属性长度)

attribute_info     attributes     attributes_count    (属性数组)

0-3字节(判断该文件是否是虚拟机可接收的Class文件,就好像PE文件开头有个MZ)

4-7字节(版本号)

接下来为常量池中数据项

CONSTANT_Utf8_info ( 程序中的字符串常量, 类型的全限定名, 方法和字段的名称, 方法和字段的描述符, 属性相关字符串)

格式:

tag

length

bytes

例如

1

5

h

e

l

l

o

CONSTANT_NameAndType(表示了一个方法或一个字段)

tag

name_index(它指向常量池中的一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的就是方法或字段的名称)

descriptor_index(它指向常量池中的一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的就是方法或字段的描述符)

#5 = Utf8               age  

#6 = Utf8               I  

#19 = NameAndType        #5:#6          //  age:I

则有

tag 19

name 5

descriptor_index 6

CONSTANT_Integer_info(它存储的是源文件中出现的int型数据的值)

tag(3)

bytes(值)

CONSTANT_String_info(它的作用是存储文字字符串)

tag(8)

string_index(链接到CONSTANT_Utf8_info)

CONSTANT_Class_info(存储类信息)

tag(7)

name_index(CONSTANT_Utf8_info())

CONSTANT_Fieldref_info(对一个字段(变量等)的符号引用, 这个符号引用包括两部分, 一部分是该字段所在的类, 另一部分是该字段的字段名和描述符)

tag

class_index(CONSTANT_Class_info)

name_and_type_index(CONSTANT_NameAndType_info)

CONSTANT_Methodref_info(一个类中方法的符号引用)

tag(10)

class_index(CONSTANT_Class_info)

name_and_type_index(CONSTANT_NameAndType_info)

CONSTANT_InterfaceMethodref_info(接口,都差不多)

fields

field_info结构如下:

access_flags(字段的访问标志,public,private,protected,static,final,volatile,transient等)

name_index (常量池的索引,名称,CONSTANT_Utf8_info)

descriptor_index(指向常量池的索引,描述)

attributes_count(表示这个字段有几个属性)

attributes(各个属性数组,属性一般有三种,ConstantValue, Deprecated, Synthetic)

methods

method_info结构如下:

access_flags(字段的访问标志,public,private,protected,static,final,volatile,transient等)

name_index (常量池的索引,名称,CONSTANT_Utf8_info)

descriptor_index(指向常量池的索引,描述)

attributes_count(表示这个字段有几个属性)

attributes(各个属性数组,属性一般有四种,Code, Deprecated, Exceptions 和Synthetic)

attributes

attribute结构:

attribute_name_index(2字节)(指向一个CONSTANT_Utf8_info,存放当前属性名)

attribute_length(4字节)(当前属性的长度,也就是info的长度)

info

info:

sourcefile_index:(指向一个常量池索引)

类型有:

SourceFile(描述了该类是从哪个源文件中编译来的, 注意, 描述的是源文件, 而不是类, 一个源文件中可以存在多个类。)

InnerClasses 描述的是内部类和外围类的关系

Synthetic表示这个字段, 方法或类不是有用户代码生成的(即不存在与源文件中), 而是由编译器自动添加的。(内部类啥的)

ConstantValue(静态字段才可以有ConstantValue属性)

Deprecated(源文件中出现的@deprecated注解,表示类过时等等)

Exceptions(描述的是方法声明的可能会抛出的异常)

Code(最重要的属性,存放方法的字节码指令(代码), 除此之外还存放了和操作数栈,局部变量相关的信息)

结构:

attibute_name_index

attribute_length

max_stack    (当前方法被执行引擎执行的时候, 在栈帧中需要分配的操作数栈的大小)

max_locals    (当前方法被执行引擎执行的时候, 在栈帧中需要分配的局部表量表的大小)

code_length

code    (字节指令,代码)

exception_table_length

exception_table    (异常表,对方法体中try-catch_finally的描述)

attributes_count

attributes    (其他属性)

LineNumberTable属性存在于Code属性中:

它建立了字节码偏移量到源代码行号之间的联系(这个可能就是jvm计数器相关,返回行号)

LocalVariableTable属性存在于Code属性中:

建立了方法中的局部变量与源代码中的局部变量之间的对应关系,(所谓的局部变量表)

       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java .class文件结构