实例探索Class文件(6)

不出所料,start_pc就是异常处理器起始位置相对该段代码的偏移量, 
end_pc就是异常处理器结束位置相对该段代码的偏移量, 
handler_pc就是异常处理器第一条指令相对该段代码的偏移量 
catch_type指向描述该异常类型(java/lang/Throwable或其子类)的CONSTANT_Class常量池索引,二若catch_type为0,那么异常处理器将处理所有异常

(2).LineNumberTable 
行号表与ELF/PE文件看上去有着异曲同工之妙,它同样建立了方法的字节码偏移量和源代码行号之间的映射关系。其info域结构如下

TypeNameCount
u2   line_number_table_length   1  
line_number_info   line_number_table   line_number_table_length  

line_number_table_length描述了行号表的项数,注意,并不是行号表各项并不是逐行对应,而是可能按照任何顺序排列,并且可能多项对应同一行。 
line_number_info的结构如下:

line_number_info{ start_pc u2, line_number u2, }

其中,start_pc描述了该行起始第一个字节码对应该段代码的偏移量,line_number描述了对应的行号。

(3).LocalVariableTable 
这里由LocalVariableTable保存了方法的栈帧中局部变量域源代码中局部变量的名称和描述符之间的映射关系。

同样,局部变量表也是以local_variable_table_length个local_variable_info结构进行组织的 

local_variable_info的结构如下:

local_variable_info{ start_pc u2, length u2, name_index u2, descriptor_index u2, index u2, }

start_pc为该段代码中指令开始位置的便宜

length为从start_pc开始的、所有局部变量有效的代码的长度(即由[start_pc, start_pc + length]描述了局部变量的作用域)

name_index为该局部变量简单名称的CONSTANT_Utf8常量池索引

descriptor_index为该局部变量描述符的CONSTANT_Utf8常量池索引

index为在此方法的栈帧中局部变量部分的索引 
需要明白,local_variable_info建立了源代码中局部变量名称、类型和其在字节码的作用域、以及栈帧中的索引之间的联系,因方法区这一特殊的结构而存在。

(4).Exceptions属性 
区别于描述Code属性的exception_table部分,这里是方法可能会抛出的异常,而非包围代码的try/catch异常。Exceptions属性的info域格式如下:

TypeNameCount
u2   number_of_exceptions   1  
u2   exception_index_table   number_of_exceptions  

exception_index_table是该方法抛出的异常类型的CONSTANT_Class常量池索引,number_of_exceptions指出了抛出异常类型的数量。 

methods部分的解析可以参考?id=b1c762ba1ee4874a23eb8a512cccf507&type=note 
10.attributes_count/attributes(属性数和属性) 
最后还有两种属性:InnerClass和SourceFile 
(1).SourceFile 
其info结构为:

TypeNameCount
u2   sourcefile_index   1  

给出了指向源文件名的CONSTANT_Utf8常量池索引 
如该class文件最后的attributes_count为1,其 
attribute_name_index为0x0033,指向51号常量池,即”SourceFile”属性 
attribute_length为0x02,即2个字节 
sourcefile_index为0x0034,指向52号常量池,即源文件名为”TestClass.java”

(2).InnerClasses

TypeNameCount
u2   number_of_classes   1  
classes_info   classes   number_of_classes  

classses_info描述了内部类(成员嵌套类、局部嵌套类和匿名嵌套类)的信息,其结构如下:

classes_info{ inner_class_info_index u2, outer_class_info_index u2, inner_name_index u2, inner_class_access_flags u2, }

inner_class_info_index指向所定义的内部类的CONSTANT_Class常量池的索引

outer_class_info_index指向该内部类的外围类的CONSTANT_Class常量池的索引,若该内部类不是一个成员嵌套类,其值为0

inner_name_index为该内部类的简单名称的CONSTANT_Utf8_info索引,当该内部类为匿名内部类时,其值为0

inner_class_access_flags是对该内部类的访问标志

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/21d552f6d5eec79a30d2df013e6c86d7.html