java源文件—–> 通过javac ——–>完成源文件的解析、注解处理、属性标注、检查泛型等等 ——-> 编译成class文件 ——> classLoader 加载
本文主要是记录字节码(class文件)的结构:
1、class文件的结构
ClassFile{
{//class文件头部
u4 magic 头部验证码 4byte
u2 minjor version 最小解析版本号(最小0,可忽略)2byte
u2 major version 最大解析版本号 2byte
},{
u2 constant_pool_count 常量池入口位置下标const #11 2byte
cp_info{ 常量池信息,遍历获取到的
u1 tag 常量池类型 1byte
u1 info[]
如果tag类型为class,2byte记录class常量池的位置 2byte
其他类型:Fieldref,Methodref,InterfaceMethodref: 4byte
2byte标示class常量的位置,2byte标示NameAndType的信息
}
},{// 类的基本描述
u2 access_flags 标示class的修饰符 2byte
u2 this_class 标示类名的常量池位置 2byte
u2 super_class 标示父类的常量池位置 2byte
u2 interface_count 接口数量 2byte
u2 interface[interface_count] 每个接口的信息 每个2byte
},{
u2 field_count 属性数量 2byte
field_info fields[field_count] 属性
{
u2 access_flags 属性修饰符 2byte
u2 name_index 属性名称 2byte
u2 descriptor_index
u2 attributes_count 附加属性数量 2byte
atturbute_info attributes[attribute_count]
}
},{
u2 method_count 方法个数 2byte
method_info{
u2 access_flags 修饰符 2byte
u2 name_index 名称 2byte
u2 descriptor_index 入口参数和返回值 2byte
u2 attributes_count body的个数 2byte
attribute_info attributes[attributes_count]
body有类型之分:
1、有指令的code列表
2、Exception标志抛出的异常
3、StackMapTable 操作数栈的位置
4、LineNumberTable 记录行号对应表
5、LocalVariableTable记录本地变量列表
如果attribute_name获取的值为Code,则代表代码执行列表
内部结构如些
Code_attribute{
u2 attribute_name_index;
u2 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{
u2 start_pc; try开始位置
u2 end_pc; try结束位置
u2 handler_pc; try跳转的目标
u2 catch_type; try异常的类型
}
}
注意:如果是code开头,LineNumberTable,StackMapTable异常信息都会包含进来.
有的编译器,会先编译生成Exception,然后在声明其他的,
}
},{
u2 attribute_count class的attribute个数
attributes[attribute_count] 如innerclass内部类,sourceFile等等
}
}
java常量基本类型在字节码中的规范定义:
类型字符 | 对应类型 | 说明 |
---|---|---|
B | byte | 不表示Byte |
Z | boolean | 基本类型和引用类型有区别,不在一一描述 |
S | short | |
C | char | |
I | int | I标示int,Integer应该标示为Ljava/lang/Integer,依次类推 |
J | long | |
F | float | |
D | double | |
V | void | 没有返回值 |
LClassName | refrerence | 引用类,例如string别标示为Ljava/lang/string |
[ | Array.refrerence | 标示数组,例如:double[][]:标示[[D; String[] 被标示为[Ljava/lang/String; |
本文摘自java特种兵第三章字节码的结构