在前面魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引,接口索引集合,字段表集合,方法表集合,那么接下来就是属性表集合了.
在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文件的工具有很多,我们可以直接看解析出来的文件就可以了).