实现语言无关性的基础仍然是虚拟机和字节码存储格式。Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了Java虚拟机指令集和符号表以及若干其他辅助信息。
一、Class类文件的结构
可参考《Java虚拟机规范》
Class文件时一组一8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要用8位字节以上空间的数据项时,则会按照高位在前(大端)的方式分割若干个8字节进行存储。
只有两种数据类型:无符号数和表
- 魔术与Class文件的版本
- 常量池
- 访问标志
- 类索引、父类索引与接口索引集合
- 字段表集合
标识字符 | 含义
-----|
B|基本类型byte
C|char
D|double
F|float
I|int
J|long
S|short
Z|boolean
V|void
L|对象类型,如Ljava/lang/Object
- 方法表集合
属性表集合
属性名称 |
---|
Code |
ConstantValue |
Deprecated |
Exceptions |
EnclosingMehod |
InnerClass |
LineNumberTable |
LocalVariableTable |
StackMapTable |
Signature |
SourceFile |
SourceDebugExtension |
Synthetic |
LocalVariableTypeTable |
RuntimeVisibleAnnotations |
RuntimeInvisibleAnnotations |
RuntimeVisibleParameter Annotations |
RuntimeInvisibleParameter Annotations |
AnnotationDefault |
BootstrapMethods |
二、字节码指令
Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包括操作数,只有一个操作码。
操作码长度为一个字节(0~255)。
字节码与数据类型
前缀 | 代表 |
---|---|
i | int |
l | long |
s | short |
b | byte |
c | char |
f | float |
d | double |
a | reference |
push、const、load...
加载和存储指令
load
store
push
wide
运算指令
add
sub
mul
div
rem
neg
shl、shr
or
and
xor
iinc
cmpg
类型转换指令
i2b i2c i2s l2i f2i f2l d2i d2l d2f
对象创建与访问指令
new
newarray anewarray multianewarray
getfield putfield getstatic putstatic
baload caload...
bastore castore
arraylength
instanceos checkcast
操作数栈管理指令
pop pop2
dup
swap
控制转移指令
if
tableswitch
goto
方法回调和返回指令
invokevirtual
invokeinterface
invokespecial
invokestatic
invokedynamic
异常处理指令
athrow
同步指令
monitorenter
monitorexit