Field TypeEntry Type
long
CONSTANT_Long
float
CONSTANT_Float
double
CONSTANT_Double
int, short, char, byte, boolean
CONSTANT_Integer
String
CONSTANT_String
4.7.3 Code属性
code属性是一个变长属性,在method_info结构的attributes表中。Code属性包含方法的Java虚拟机指令和辅助信息,包括实例初始化方法或类或接口初始化方法(2.9)。
如果该方法是native或abstract,则其方法信息结构的属性表中必须没有Code属性。否则,它的方法信息结构的属性表中必须只有一个Code属性。
Code属性的格式如下:
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
结构体的各项如下:
attribute_name_index
attribute_name_index的值必须是常量池表中的有效索引。该索引处的常量池条目必须是一个表示字符串“Code”的常量Utf8信息结构(4.4.7)。
attribute_length
指示了属性的长度,不包含开头的6个字节。
max_stack
它的值给出了这个方法在执行过程中这个方法的操作数栈的最大深度。
max_locals
max_locals项的值给出了在调用此方法(2.6.1)时分配的局部变量数组中的局部变量的数量,包括用于在调用时向方法传递参数的局部变量。
long或double类型的值的最大局部变量索引是max_locals - 2。任何其他类型的值的最大局部变量索引是max_locals - 1。
code_length
它的值给出了这个方法的code数组中字节的数量。
它的值必须大于0小于65535,也就是说code数组不能为空。
code[]
code数组给出了实现了这个方法的java虚拟机代码的实际的字节。
当代码数组在字节可寻址机器上读入内存时,如果数组的第一个字节在4字节的边界上对齐,tableswitch和lookupswitch32位的偏移量将是4字节对齐的。(有关代码数组对齐结果的更多信息,请参考这些说明的描述。)
关于代码数组内容的详细约束非常广泛,在单独的小节(4.9)中给出。
exception_table_length
它的值给出了exception_table表条目的个数。
exception_table[]
exception_table数组中的每个条目都描述了代码数组中的一个异常处理程序。异常表数组中处理程序的顺序很重要(2.10)。
每个exception_table条目包含以下四项:
start_pc,end_pc
两个项目start_pc和end_pc的值指示异常处理程序在代码数组中的有效范围。start_pc的值必须是指令操作码代码数组的有效索引。end_pc的值必须是指令操作码的代码数组的有效索引,或者必须等于代码数组的长度code_length。start_pc的值必须小于end_pc的值。
start_pc是包含性的,end_pc是排他性的;也就是说,当程序计数器在[start_pc, end_pc),异常处理程序必须是有效的。
end_pc是排他的这一事实是Java虚拟机设计中的一个历史错误:如果一个方法的Java虚拟机代码正好是65535字节长,并且以1字节长的指令结束,则该指令不能被异常处理程序保护。编译器编写器可以通过将任何方法、实例初始化方法或静态初始值设定项(任何代码数组的大小)的生成的Java虚拟机代码的最大大小限制为65534字节来解决这个错误。
handler_pc
它的值指示了异常处理程序的起始位置。它的值必须是code数组的有效索引并且是指令操作码的索引。
catch_type
如果catch_type项的值非零,它必须是常数池表中的有效索引。该索引处的常量池条目必须是CONSTAN_Class_info结构(4.4.1),表示该异常处理程序指定要捕获的一类异常。只有当抛出的异常是给定类或其子类之一的实例时,才会调用异常处理程序。
验证器检查该类是可抛出的或者可抛出的子类(4.9.2)。
如果catch_type项的值为零,则为所有异常调用此异常处理程序。
这用于实现finally(3.13)。
attributes_count
它的值只是了Code属性的属性数量。
attributes[]
属性表的每个值必须是attribute_info结构(4.7)。
Code属性可以有任意数量的可选属性与之关联。
本规范定义的出现在Code属性的属性表中的属性列在表4.7-C中
4.7给出了Code属性的属性表中定义的属性规则。
Code属性的属性表中关于非预定义属性的规则在4.7.1中给出。