JVM虚拟机---(12)Class文件结构之属性表集合

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq1021979964/article/details/97785731

属性表集合

        对于字段表出现的ConstantValue和方法表出现的Code,LineNumberTable属性表集合是不是不太理解,在没有看到属性表之前,我看那两个也是有点懵逼,现在就专门说属性表。

       属性表(attribute_info)在字段表和方法表都有出现过,在Class文件、字段表、方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。

       与Class文件中其它的数据项目要求严格的顺序、长度和内容不同,属性表集合的限制稍微宽松一些,不再要求各个属性表具有严格顺序,并且只要不与已有属性名重复,任何人实现的编译器都可以像属性表写入自己定义的属性信息,Java虚拟机运行时会忽略掉它不认识的属性。

        对于每个属性,它的名称需要从常量池中引用一个CONSTANT_Utf8_info类型的常量来表示,而属性值的结构则是完全自定义的,只需要通过一个u4的长度属性去说明属性值所占用的位数即可,

 

在这里只介绍Code属性,就不一一介绍了

1.Code属性

方法体中的代码经过Javac编译器处理后,最终变为字节码指令存储在Code属性内,Code属性出现在方法表的属性集合之中,但并不是所有的方法都必须存在这个属性,例如接口、抽象类的方法就不存在于Code属性。

2.案例代码

public class TestMethod {

    public int add(int a,int b) {
		return a+b;
	}

}

我偷懒点,又不太准确的方式去找这个属性表,在javap中获取到属性表的名称Code,得到对应的数据是6,再到class文件中找。

3.构造方法的属性案例

  1. 属性表名称索引:0x0006(对应十进制为6),指向常量池的第6,为Code,表示是Code类型的属性表。
  2. 属性长度:0x0000 001D(对应十进制的29),表示后续29个字节是表示这个Code属性表的信息。
  3. 操作数栈的最大深度:0x0001(对应十进制的1),表示栈帧中操作数栈的最大深度是1。
  4. 局部变量表的最大容量:0x0001(对应十进制的1),JVM调用该方法时,根据这个值设置栈帧中的局部变量表的大小。
  5. 机器指令数目:0x0000 0005,表示后续的5个字节是机器指令集。
  6. 机器指令集:0x002A、0x00B7、0x0000、0x0001、0x00B1。
  7. 异常表:0x0000,表示异常为0。
  8. Code属性的属性表集合:0x0001,表示后面还有一个属性表。后面跟着这个属性。

如果再看的话,那就是0x0007:对应常量池,是LineNumberTable。这个就不用说了。

别忘了,这个是默认的无参构造器的属性表,想找add,还的继续找。

4.自定义方法属性案例

  1. 属性表名称索引:0x0006(对应十进制为6),指向常量池的第6,为Code,表示是Code类型的属性表。
  2. 属性长度:0x0000 001C(对应十进制的28),表示后续28个字节是表示这个Code属性表的信息。
  3. 操作数栈的最大深度:0x0002(对应十进制的2),表示栈帧中操作数栈的最大深度是2。
  4. 局部变量表的最大容量:0x0003(对应十进制的3),JVM调用该方法时,根据这个值设置栈帧中的局部变量表的大小。
  5. 机器指令数目:0x0000 0004,表示后续的4个字节是机器指令集。
  6. 机器指令集:0x001B、0x001C、0x0060、0x00AC。
  7. 异常表:0x0000,表示异常为0。
  8. Code属性的属性表集合:0x0001,表示后面还有一个属性表。后面跟着这个属性。

如果再看的话,那就是0x0007:对应常量池,是LineNumberTable。这个就不用说了。

 

猜你喜欢

转载自blog.csdn.net/qq1021979964/article/details/97785731
今日推荐