实例探索Class文件(5)

class文件field域解析: 
首先由开头两个字节看出有5个field_info 

field1: 
access_flag为ACC_PRIVATE,标志其为private类型 
name_index为0x0007,指向7号常量池,即简单名称为”private_global” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为0,即没有任何属性 

field2: 
access_flag为ACC_PUBLIC,标志其为public类型 
name_index为0x0009,指向9号常量池,即简单名称为”public_global” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为0,即没有任何属性 

field3: 
access_flag为0x0010|0x0008|0x0002,即ACC_FINAL | ACC_STATIC | ACC_PRIVATE,标志其为private static final类型 
name_index为0x000A,指向10号常量池,即简单名称为”sfi” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为1,即有一个属性 

该属性的 
attribute_name_index为0x000B,指向11号常量池,即”ConstantValue”属性 
attribute_length为2,即固定2个字节 
constantvalue_index为0x000C,指向12号常量池,即sfi的值为”127”(这里还是字符串) 

field4: 
access_flag为0x0010|0x0008|0x0001,即ACC_FINAL | ACC_STATIC | ACC_PUBLIC,标志其为public static final类型 
name_index为0x000D,指向13号常量池,即简单名称为”sfs” 
descriptor_index为0x000E,指向14号常量池,即描述符为”Ljava/lang/String;” 
attributes_count为1,即有一个属性 

该属性的 
attribute_name_index为0x000B,指向11号常量池,即”ConstantValue”属性 
attribute_length为2,即固定2个字节 
constantvalue_index为0x000F,指向15号常量池,即sfs的值为”test strings” 

field5: 
access_flag为ACC_PRIVATE,标志其为private类型 
name_index为0x0011,指向17号常量池,即简单名称为”sb” 
descriptor_index为0x0012,指向18号常量池,即描述符为”Ljava/lang/StringBuilder;” 
attributes_count为0,即没有任何属性 

9.methods_count/methods(方法数/方法) 
方法域的method_info结构与字段域是一样的,即

method_info{ access_flags u2, name_index u2, descriptor_index u2, attributes_count u2, attributes attributes_info * attributes_cout }

不过其access_flag有些不同

实例探索Class文件

如果一个方法是抽象方法,那么它就不能为private、static、final、synchronized、native和strict类型

方法域出现的属性有Code、Deprecated、Exceptions、Synthetic 
下面介绍新出现的两种属性Code和Exceptions: 
(1).Code 
其info域的结构如下

实例探索Class文件

 

其中:

max_stack标志该方法执行的任意时刻,其操作数栈的最大长度(以字为单位)

max_locals标志改方法的局部变量所需存储空间的长度(以字为单位)

code_length给出了该方法字节码部分的长度(以字节为单位)

code_length长度的字节码

exception_table_length是异常表的长度,紧接着是exception_table_length个exception_info所描述的异常信息

最后就是该段代码的属性描述,这是一个嵌套的属性描述,会出现两个新的属性LineNumberTable和LocalVariableTable,即行号表和局部变量表

首先看exception_table_info的结构,可以预见,一个异常在代码中的描述就必须包含作用域、异常类型和异常处理三部分内容,看看exception_table_info是不是这样组织的

exception_table_info{ start_pc u2, end_pc u2, handler_pc u2, catch_type u2, }

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

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