java.class文件结构学习

xiaoxiao2021-02-28  95

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属性中: 建立了方法中的局部变量与源代码中的局部变量之间的对应关系,(所谓的局部变量表)        
转载请注明原文地址: https://www.6miu.com/read-67200.html

最新回复(0)