Java技术点速记 | 字节码与类文件
java之所以可以“一次编写,到处运行(Write Once, Run Anywhere)”,是因为java代码被翻译成各个平台的java虚拟机都可以理解的程序存储格式——字节码(Byte Code)。
java语言中的各种语法、关键字、变量常量和运算符号的语义最终都会由多条字节码指令组合来表达,使用Java编译器可以吧Java代码编译成储存字节码的Class文件。
Class类文件结构
Class文件是一组以8个字节为基础单位的二进制流。
Class文件结构由“无符号数”和“表”两种数据类型构成。
无符号数是属于这种结构里基本的数据类型:u1,u2,u4,u8分别代表1,2,4,8个字节,可以用来描述数字,索引引用,数量值,和UTF-8编码构成字符串值。
表是由无符号数以及其他的表作为数据项构成的复合数据类型。整个Class文件也可以视作一张表,这张表由下表所示严格按顺序构成。
依次为:
名称 | 类型 | 数量 |
---|---|---|
魔数(magic) | u4 | 1 |
子版本号(minor_version) | u2 | 1 |
主版本号(major_version) | u2 | 1 |
常量池计数值(constant_pool_count) | u2 | 1 |
常量池(constant_pool) | cp_info | constant_pool_count-1 |
访问标志(access_flag) | u2 | 1 |
类索引(this_class) | u2 | 1 |
父类索引(super_class) | u2 | 1 |
接口计数值(interfaces_count) | u2 | 1 |
接口索引集合(interfaces) | u2 | interface_count |
字段表集合计数器(fields_count) | u2 | 1 |
字段表集合(fields) | field_info | fields_count |
方法表集合计数器(methods_count) | u2 | 1 |
方法表集合(methods) | method_info methods_count | |
属性表集合计数器(attributes_count) | u2 | 1 |
属性表集合(attributes) | attribute_info | attributes_count |
字节码指令
Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成。
下图很好地解释了虚拟机栈及其中的操作数栈。
字节码文件及字节码指令介绍了一部分指令,实际上Java字节码指令一共有:
- 加载和存储
- 运算
- 类型转换
- 对象创建与访问
- 操作数栈管理
- 控制转移
- 方法调用和返回
- 异常处理
- 同步
这九类指令。