Class文件

载体

  • 二进制流
  • 字节为单位,没有分隔符,大端编码(高位在前)
  • 由无符号数(u1|u2|u4|u8)和表(*_info)构成
类型 名称 数量
u4 magic 1
u2 minor_version 1
u2 major_version 1
u2 constant_pool_count 1
cp_info constant_pool constant_pool_count - 1
u2 access_flags 1
u2 this_class 1
u2 super_class 1
u2 interfaces_count 1
u2 interfaces interfaces_count
u2 fields_count 1
field_info fields fields_count
u2 methods_count 1
method_info methods methods_count
u2 attributes_count 1
attributes_info attributes attributes_count

魔数与版本号

u4: 0xCAFEBABE
版本号以主版本号为主(45开始),只能向下兼容
JDK1.1支持45.0-45.65535
JDK1.2支持45.0-46.65535
JDK1.7支持45.0-51.65535
但使用编译器输出的Class文件的版本号,除了和编译器本身的版本相关外,还可以使用-target参数向前指定

常量池

常量池第0项保留,所以数量为常量池容量+1
表项内容详见《深入理解Java虚拟机》p172

访问标志

0x0001:ACC_PUBLIC
0x0010:ACC_FINAL
0x0020:ACC_SUPER(JDK1.0.2后为真)
0x0200:ACC_INTERFACE
0x0400:ACC_ABSTRACT
0x1000:ACC_SYNTHETIC(不由代码产生)
0x2000:ACC_ANNOTATION
0x4000:ACC_ENUM

类索引、父类索引、接口索引集合

类索引:u2指向常量池中一个类型为Constant_Class_info的类描述符,描述了类的全限定名
父类索引:u2指向常量池中一个类型为Constant_Class_info的类描述符,描述了父类的全限定名
接口索引:u2的接口计数器,计数器个u2类型的类描述符

字段表集合

field_info

一个字段项包括如下部分:

  • u2: access_flags 字段修饰符
  • u2: name_index 简单名称
  • u2: desciptor_index 描述符
  • u2: attribute_count 属性表计数器
  • attribute_info: attributes 属性表集合
name_index, descriptor_index 字段名称和描述符

分别指向了常量池中的名称和类型,相当于常量池中的nameAndType
描述符标识字符含义

字符 含义 字符 含义
B byte J long
C char S short
D double Z boolean
F float V void
I int L 对象,Ljava/lang/Object

数组类型前置一个[,java.lang.String[][]为[[Ljava/lang/String

attributes 属性表集合

attributes用来描述额外信息,如初始值等

注意

不会包括继承字段,但可能会包括未定义字段,如内部类保持一个外部类的引用

方法表集合

结构与字段表一样

descriptor_index 描述符

先参数列表,按顺序放在()之中,然后跟着返回值类型
void inc() --> ()V
String toString() --> ()Ljava/lang/String;

注意

不会包括没有重写的父类方法;
如果没有显示定义的构造函数,会添加一个名为""的实例构造器;
方法中也可能会有类构造器"";
Class文件中的方法重载,只要描述符不完全一样即可,也就是可以通过返回值区分;
方法中的代码会放在方法属性表集合中一个名为"Code"的属性里。

属性表集合

字段,方法,Class文件,Code属性都可以包括各自的属性表集合。

属性表元素结构

u2:attribute_name_index 指向常量池一个utf8
u4:attribute_length 属性值的长度
u1:info

方法属性表
名称 含义
Code Java代码编译成的字节码指令
Exceptions 方法抛出的异常
Deprecated 被D的方法(boolean)
Signature 用于泛型情况下的方法签名,避免擦除后签名混乱
Synthetic 标识自动生成的方法(boolean)
RuntimeVisibleAnnotations 指明运行时可见的注解
RuntimeInvisibleAnnotations 运行时不可见的注解
RuntimeVisibleParameterAnnotations 运行时可见的方法参数注解
RuntimeInvisibleParameterAnnotations 运行时不可见的方法参数注解
AnnotationDefault 注解类元素的默认值

Code属性

类型 名称 含义
u2 attribute_name_index Code
u4 attribute_length 属性值的长度
u2 max_stack 操作数栈最大深度(用于栈帧中分配)
u2 max_locals 局部变量表需要的空间,32位以下的数据类型一个Slot,以上的两个Slot,包括了方法参数、局部变量、this、异常参数(catch)等,但由于作用域的问题,Slot可以复用
u4 code_length 字节码长度,最多65535条
u1 code 一条字节码指令一个字节
u2 exception_table_length 异常表长度
exception_info exception_table 异常表(深入理解Java虚拟机P186)
u2 attributes_count 属性表计数器
attribute_info attributes 属性表

Code的属性表中包括了三个个属性
LineNumberTable用于描述Java源码与字节码行号的对应关系
LocalVariableTable用于描述栈帧中局部变量表中的变量与Java源码定义的变量之间的关系
StackMapTable在虚拟机加载字节码的验证阶段被新类型检查验证器使用

字段属性表
名称 含义
ConstantValue final关键字定义的常量值
Signature 泛型
Deprecated 被D字段
Synthetic 自动生成
RuntimeVisibleAnnotations 指明运行时可见的注解
RuntimeInvisibleAnnotations 运行时不可见的注解
Class文件属性表
名称 含义
EnclosingMethod 局部类或者匿名类标识外围方法
InnerClasses 内部类列表
SourceFile 源文件名称
SourceDebugExtension 额外的调试信息
LocalVariableTypeTable 用特征签名代替描述符,描述泛型参数化类型
BootstrapMethods invokedynamic引用的引导方法限定符
Signature 泛型
Deprecated 被D字段
Synthetic 自动生成
RuntimeVisibleAnnotations 指明运行时可见的注解
RuntimeInvisibleAnnotations 运行时不可见的注解

你可能感兴趣的:(Class文件)