天天看点

JVM-CLASS文件完全解析-属性表集合

  在前面魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引,接口索引集合,字段表集合,方法表集合,那么接下来就是属性表集合了. 

  在class文件,字段表,方法表都可以携带自己的属性表集合(像前面方法表的时候就用到"code"这个属性表)以用于描述某些场景专有的信息.

  虚拟机中预定义的属性:

属性名称

使用位置

含义

Code

方法表

Java代码编译成的字节码指令

ConstantValue

字段表

final关键字定义的常量池

Deprecated

类,方法,字段表

被声明为deprecated的方法和字段

 Exceptions

方法表 

方法抛出的异常 

 EnclosingMethod

类文件 

仅当一个类为局部类或者匿名类是才能拥有这个属性,这个属性用于标识这个类所在的外围方法 

 InnerClass

内部类列表 

 LineNumberTable

Code属性 

Java源码的行号与字节码指令的对应关系 

 LocalVariableTable

方法的局部便狼描述 

 StackMapTable

JDK1.6中新增的属性,供新的类型检查检验器检查和处理目标方法的局部变量和操作数有所需要的类是否匹配 

 Signature

类,方法表,字段表 

 用于支持泛型情况下的方法签名

 SourceFile

记录源文件名称 

 SourceDebugExtension

用于存储额外的调试信息 

 Synthetic

标志方法或字段为编译器自动生成的 

 LocalVariableTypeTable

类 

使用特征签名代替描述符,是为了引入泛型语法之后能描述泛型参数化类型而添加 

 RuntimeVisibleAnnotations

为动态注解提供支持 

 RuntimeInvisibleAnnotations

表,方法表,字段表 

用于指明哪些注解是运行时不可见的 

 RuntimeVisibleParameterAnnotation

作用与RuntimeVisibleAnnotations属性类似,只不过作用对象为方法

 RuntimeInvisibleParameterAnnotation 

 方法表

 作用与RuntimeInvisibleAnnotations属性类似,作用对象哪个为方法参数

 AnnotationDefault

用于记录注解类元素的默认值 

 BootstrapMethods

用于保存invokeddynamic指令引用的引导方式限定符  

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

  属性表定义的结构:  

类型

名称

数量

u2

attribute_name_index

1

attribute_length

u1

info

  Java程序方法体中的代码经过Javac编译处理后,最终变为字节码指令存储在Code属性中.Code属性出现在方法表的属性集合中,但是并非所有的方法表都有这个属性.例如接口或类中的方法就不存在Code属性了.

  在字节码指令之后的是方法的是方法的显式异常处理表集合,异常表对于Code属性来说并不是必须参在的.

  结构:  

u4

max_stack

max_locals

code_length

code

exception_table_length

exception_info

exception_table

exception_length

attributes_count

attribute_info

attributes

   

  Exception属性的作用是列出方法中能抛出的受查异常Check Exceptions,也就是方法描述时在throws关键字之后列举的异常

  结构:

attribute_lrngth

attribute_of_exception

exception_index_tsble

number_of_exceptions

  Exception属性中的number_of_exceptions项表示方法可能抛出的number_of_exceptions种受查异常,每一种受查异常使用一个exception_index_tsble项表示,exception_index_tsble是一个指向常量池中CONSTANT_Class_info型常量的索引,代表了该受查异常的类型.

line_number_table_length

line_number_info

line_number_table

  line_number_table是一个数量为line_number_table_length,类型为line_number_info的集合,line_number_info表包括了start_PC和line_number两个u2类型的数据项,前者是字节码行号,后者是Java源代码行号.

虚拟机预定义的属性有20多个,就不意一一介绍,基本上和上述的几个属性差不多.

到这里calss文件的文件解析也终于要告一段落了(写了好长时间,其实我最讨厌看这些字节码了,其实一般程序员只需要了解一下class文件的构成和原理就行了,解析class文件的工具有很多,我们可以直接看解析出来的文件就可以了).