Java虚拟机精讲【2.3】
3.6.2 ConstantValue属性和 Code 属性一样, ConstantValue 属性同样也属于 Java 虚拟机必须识别出的 3 个属性之一, ConstantValue 属性位于 field_info 项的属性表中。在一个 field_info 项的属性表中最多只允许包含一个 ConstantValue 属性,该属性主要用于通知 Java 虚拟机对代码中的类变量(这里并不包括实例变量)执行初始化操作。简单来说,类变量的初始化操作有两种方式:一种是由类(接口)初始化方法clinit()完成,而另一种则由 ConstantValue 属性完成。如果一个类变量被 final 和 static 这两个关键字修饰后,并且数据类型是原始类型或者java.lang.String 类型的话,这个类变量就能够被 ConstantValue 属性执行初始化操作,反之一个类变量如果并没有被 final 关键字修饰,或者数据类型并非是原始类型或者 java.lang.String类型,那么则只能由clinit()方法完成其初始化操作。关于clinit()方法究竟是如何对类变量执行初始化操作的,请阅读 7.2.5 节。参考《 Java 虚拟机规范( Java SE7 版)》的描述来看, Java 虚拟机只是强制要求了field_info 表中的 access_flag 项必须设置有 ACC_STATIC 标志,而 ACC_FINAL 标志并非是必需的,它只是一个可选项,因为仅仅只是前端编译器对 final 关键字有要求而已。在此大家需要注意,如果 field_info 表中的 access_flag 项并没有被设置 ACC_STATIC 标志时,那么Java 虚拟机将必须忽略掉它。 ConstantValue 属性的表结构信息,如下所示:代码 3-23 ConstantValue_attribute 表结构 ConstantValue_attribute { u2 attribute_name_index; u4 attribute_length; u2 constantvalue_index; }上 述 代 码 示 例 中 , attribute_name_index 项 中 的 值 是 一 个 指 向 常 量 池 列 表 中CONSTANT_Utf8_info(请阅读 3.3.1 节)常量项的有效索引,通过这个索引值即可成功获取当前属性的简单名称,即字符串“ ConstantValue”。 attribute_length 项的值被永远固定为 2。而 constantvalue_index 项中的值则是一个指向常量池列表中 CONSTANT_Long_info(请阅读3.3.4 节)、 CONSTANT_Double_info(请阅读 3.3.5 节)、 CONSTANT_Integer_info(请阅读3.3.2 节)、 CONSTANT_Float_info(请阅读 3.3.3 节)或者 CONSTANT_String_info(请阅读3.3.7 节)常量项的有效索引。3.6.3 Exceptions属性和 Code 属性以及 ConstantValue 属性一样, Exceptions 属性同样也属于 Java 虚拟机必须识 别 出 的 3 个 属 性之 一 , Exceptions 属性位于 method_info 项的属性表中。在一个method_info 项的属性表中最多只允许包含一个 Exceptions 属性,该属性主要用于列举出当前