4.7.1 定义和命名新属性

  允许编译器定义和发布的class文件在class文件结构体、field_info结构体、method_info结构体和Code结构体中的attributes表中包含新的属性。允许java虚拟机识别和使用attributes表中的新属性。但是,任何没有在class文件规范中定义的属性都不能影响class文件的语义。java虚拟机的实现需要忽略它们不能识别的属性。

  例如,允许定义一个新属性来支持特定供应商的调试。因为java虚拟要需要忽略它们不能识别的属性,为特殊java虚拟机实现所使用的class文件也可以用于其它的java虚拟机实现,尽管这些实现不能使用class文件中包含的额外调试信息。

  禁止java虚拟机实现仅因为存在一些新属性就抛出异常或者拒绝使用class文件。当然,运行class文件的工具可能不能正确工作,如果给定的class文件中没有包含它们需要的属性。

  两个本来是不同的属性,但是碰巧使用了相同的属性名并且长度相同,虚拟机实现在识别这两个属性时会发生冲突。除本规范中定义的属性外,其他属性的名称必须根据《Java语言规范,Java SE 8版》(JLS 6.1)中描述的包命名约定进行选择。

  这个规范的未来版本可能定义额外的属性。

4.7.2 ConstantValue属性

  ConstantValue属性的长度时固定的,它在field_info结构的attributes表中。ConstantValue属性表示常量表达式的值,用于以下场景:

  • 如果在field_info结构的access_flags项中设置了ACC_STATIC标志,那么field_info结构所表示的字段将被分配其ConstantValue属性所表示的值,作为声明该字段的类或接口初始化的一部分(5.5)。这发生在调用该类或接口的类或接口初始化方法之前(2.9)。
  • 否则,java虚拟机必须忽略这个属性

  field_info结构中的attributes表中最多只能有一个ConstantValue属性。

  ConstantValue属性的格式如下:

ConstantValue_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;
}

  ConstantValue_attribute结构的各条目如下:

  attribute_name_index

    attribute_name_index的值必须是常量池表中的有效索引。该索引处的常量池条目必须是一个表示字符串“ConstantValue”的常量Utf8信息结构(4.4.7)。

  attribute_length

    它的值必须是2.

  constantvalue_index

    constantvalue_index的值必须是常量池表中的有效索引。该索引处的常量池条目给出由该属性表示的常量值。常量池条目必须是与字段相适应的类型,如表4.7.2-A所指定。

Table 4.7.2-A. 常量属性类型

Field Type Entry Type
long CONSTANT_Long
float CONSTANT_Float
double CONSTANT_Double
intshortcharbyteboolean 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中给出。

java虚拟机规范(se8)——class文件格式(五)的更多相关文章

  1. java虚拟机规范(se8)——class文件格式(四)

    4.7 属性 属性用于class文件格式中的ClassFile,field_info,method_info和Code_attribute结构. 所有的属性都是下面的格式: attribute_inf ...

  2. java虚拟机规范(se8)——class文件格式(一)

    第四章 class文件格式 本章介绍了java虚拟机的class文件格式.每一个class文件包含一个单独的类或者接口的定义.虽然类和接口不一定都定义在文件中(比如类和接口亦可以通过类加载器直接生成) ...

  3. java虚拟机规范(se8)——class文件格式(三)

    4.5 字段 字段使用field_info结构来描述. 在同一个class文件中的两个字段不能有相同的名称和描述符. 结构的格式如下: field_info { u2 access_flags; u2 ...

  4. java虚拟机规范(se8)——class文件格式(七)

    4.7.5 Exceptions 属性 Exceptions 属性是一个变长属性,它位于 method_info(§4.6)结构的属性表中. Exceptions 属性指出了一个方法需要检查的可能抛出 ...

  5. java虚拟机规范(se8)——class文件格式(二)

    4.4 常量池 java虚拟机指令并不依赖类.接口.类实例或者数组的运行时布局.相反,指令依靠常量池中的符号信息. 所有的常量池条目都有如下的通用结构: cp_info { u1 tag; u1 in ...

  6. java虚拟机规范(se8)——class文件格式(六)

    4.7.4 StackMapTable 属性 StackMapTable 属性是一个变长属性,位于 Code(§4.7.3)属性的属性表中.这个属性会在虚拟机类加载的类型阶段(§4.10.1)被使用. ...

  7. java虚拟机规范(se8)——java虚拟机结构(一)

    本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述 ...

  8. java虚拟机规范(se8)——java虚拟机结构(五)

    2.10 异常 java虚拟机中的异常用Throwable类或者它的子类的实例来表示.抛出一个异常会导致立即非本地(an inmediate nolocal)的控制转移,从发生异常的地方跳到处理异常的 ...

  9. java虚拟机规范(se8)——java虚拟机结构(六)

    2.11 指令集简介 java虚拟机指令由一个字节的操作码,接着时0个或多个操作数组成,操作码描述了执行的操作,操作数提供了操作所需的参数或者数据.许多指令没有操作数只包含一个操作码. 如果忽略异常处 ...

随机推荐

  1. 客户端GUI结构学习总结

    这几个月的开发工作主要是关于游戏内GUI的,业务开发之余也时常会看看客户端工程里的GUI系统这一块的代码,这里系统的总结下. 一.GUI树形结构 在GUI中所有的控件都遵循树形结构: 在客户端初始化时 ...

  2. R语言数据类型与数据结构

    一.数据类型 5种 1.character 字符 2.numeric 数值 3.integer 整数 一般数字的存储会默认为数值类型,如果要强调是整数,需要在变量值后面加上 L. x <- 5L ...

  3. React(1) --新建项目

    搭建React开发环境之前的准备工作 1.必须要安装node.js (注意:安装node.js稳定版本) 2.安装cnpm,用cnpm替代npm npm install -g cnpm --regis ...

  4. MySQL优化系列之一

    MySQL数据库常见的两个瓶颈是CPU和I/O. CPU在饱和的情况下一般发生在数据装入内存或者从磁盘上读取数据的时候,当装入的数据远大于 内存容量的时候,这时可能会发生I/O瓶颈, 如果是分布式应用 ...

  5. HTML5 arc的例子

    demo.html <!DOCTYPE html> <html lang="zh"> <head> <meta charset=" ...

  6. 每天一个linux命令:more(13)

    more more命令是一个基于vi编辑器文本过滤器,它以全屏幕的方式按页显示文本文件的内容,支持vi中的关键字定位操作.more名单中内置了若干快捷键,常用的有H(获得帮助信息),Enter(向下翻 ...

  7. Angular JS - 2 - angularjs helloworld

    材料下载  https://github.com/liuch0228/AngularJS-learn.git 1.使用原生jquery实现 实现输入框内容 在页面上跟随输入值动态更新 项目路径 < ...

  8. 阿里云HPC助力新制造 | 上汽仿真计算云SSCC

    随着上汽集团与阿里云的合作开展,阿里云各项技术逐步深入到上汽汽车研发领域的核心业务实现落地.其中上海汽车集团股份有限公司乘用车分公司(以下简称上汽乘用车)与阿里云共建的仿真计算混合云就是新制造产业升级 ...

  9. shell脚本学习 (9) 提取开头或结尾的几行

    1 提取开头的n行 用head awk或者 sed实现 do.txt sed 1q do.txt awk 'FNR <= 1' do.txt do.txt文件 2 显示行尾的几行 用tail - ...

  10. Unity编程标准导引-3.4 Unity中的对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的对象池 本节通过一个简单的射击子弹的示例来介绍T ...