class文件“基本类型”
类 型 |
描 述 |
u1 |
1个字节,无符号类型 |
u2 |
2个字节,无符号类型 |
u4 |
4个字节,无符号类型 |
u8 |
8个字节,无符号类型 |
ClassFile表的格式
类 型 |
名 称 |
数 量 |
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 |
attribute_info |
attributes |
attributes_count |
常量池标志
入 口 类 型 |
标 志 值 |
描 述 |
CONSTANT_Utf8 |
1 |
UTF-8编码的Unicode字符串 |
CONSTANT_Integer |
3 |
int类型字面值 |
CONSTANT_Float |
4 |
float类型字面值 |
CONSTANT_Long |
5 |
long类型字面值 |
CONSTANT_Double |
6 |
double类型字面值 |
CONSTANT_Class |
7 |
对一个类或接口的符号引用 |
CONSTANT_String |
8 |
String类型字面值 |
CONSTANT_Fieldref |
9 |
对一个字段的符号引用 |
CONSTANT_Methodref |
10 |
对一个类中声明的方法的符号引用 |
CONSTANT_InterfaceMethodref |
11 |
对一个接口中声明的方法的符号引用 |
CONSTANT_NameAndType |
12 |
对一个字段或方法的部分符号引用 |
- 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
access_flags项的标志位
标 志 名 |
值 |
设置后的含义 |
设 置 者 |
ACC_PUBLIC |
0x0001 |
public类型 |
类和接口 |
ACC_FINAL |
0x0010 |
类为final类型 |
只有类 |
ACC_SUPER |
0x0020 |
使用新型的invokespecial语义 |
类和接口 |
ACC_INTERFACE |
0x0200 |
接口类型,不是类类型 |
所有的接口,没有类 |
ACC_ABSTRACT |
0x0400 |
abstract类型 |
所有的接口,部分类 |
- 特殊字符串
- 全限定名
- 简单名称
- 描述符
基本类型终结符
终 结 符 |
类 型 |
B |
byte |
C |
char |
D |
double |
F |
float |
I |
int |
J |
long |
S |
short |
Z |
boolean |
字段描述符示例
描 述 符 |
字 段 声 明 |
I |
int i; |
[[J |
long[][] windingRoad; |
[Ljava/lang/Object; |
java.lang.Object[] stuff; |
Ljava/util/Hashtable; |
java.util.Hashtable ht; |
[[[Z |
boolean[][][] isReady; |
方法描述符示例
描 述 符 |
方 法 声 明 |
()I |
int getSize(); |
()Ljava/lang/String; |
String toString(); |
([Ljava/lang/String;)V |
void main(String[] args); |
()V |
void wait(); |
(JI)V |
void wait(long timeout, int nanos); |
(ZILjava/lang/String;II)Z |
boolean regionMatches(boolean ignoreCase, int toOffset, String other, int offset, int len); |
([BII)I |
int read(byte[] b, int off, int len); |
cp_info表的通常形式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
表的类型和格式 |
u1 |
info |
根据tag值决定 |
|
CONSTANT_Utf8_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Utf8(1) |
u2 |
length |
1 |
bytes项的长度(字节数) |
u1 |
bytes |
length |
按照变体UTF-8格式存储的字符串中的字符 |
CONSTANT_Integer_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Integer(3) |
u4 |
bytes |
1 |
按照高位在前的格式存储int类型值 |
CONSTANT_Float_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Float(4) |
u4 |
bytes |
1 |
按照高位在前的格式存储float类型值 |
CONSTANT_Long_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Long(5) |
u8 |
bytes |
1 |
按照高位在前的格式存储long类型值 |
CONSTANT_Double_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Double(6) |
u8 |
bytes |
1 |
按照高位在前的格式存储double类型值 |
CONSTANT_Class_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Class(7) |
u2 |
name_index |
1 |
包含类或者接口全限定名的CONSTANT_Utf8_info表的索引 |
CONSTANT_String_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_String(8) |
u2 |
string_index |
1 |
包含文字字符串值的CONSTANT_Utf8_info表的索引 |
CONSTANT_Fieldref_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Fieldref(9) |
u2 |
class_index |
1 |
声明被引用字段的类或者接口的CONSTANT_Class_info入口的索引 |
u2 |
name_and_type_index |
1 |
提供了CONSTANT_NameAndType_info入口的索引,该入口提供了字段的简单名称以及描述符 |
CONSTANT_Methodref_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_Methodref(10) |
u2 |
class_index |
1 |
声明被引用方法的类的CONSTANT_Class_info入口的索引 |
u2 |
name_and_type_index |
1 |
提供了CONSTANT_NameAndType_info入口的索引,该入口提供了方法的简单名称以及描述符 |
CONSTANT_InterfaceMethodref_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_InterfaceMethodref(11) |
u2 |
class_index |
1 |
声明被引用方法的接口的CONSTANT_Class_info入口的索引 |
u2 |
name_and_type_index |
1 |
提供了CONSTANT_NameAndType_info入口的索引,该入口提供了方法的简单名称以及描述符 |
CONSTANT_NameAndType_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u1 |
tag |
1 |
值为CONSTANT_NameAndType(12) |
u2 |
name_index |
1 |
给出了CONSTANT_Utf8_info入口的索引,该入口给出了字段或者方法的名称 |
u2 |
descriptor_index |
1 |
提供了CONSTANT_Utf8_info入口的索引,该入口提供了字段或者方法的描述符 |
field_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u2 |
access_flags |
1 |
见下方的表 |
u2 |
name_index |
1 |
提供了给出字段简单名称(不是全限定名)的CONSTANT_Utf8_info入口的索引 |
u2 |
descriptor_index |
1 |
提供了给出字段描述符的CONSTANT_Utf8_info入口的索引 |
u2 |
atrributes_count |
1 |
attributes_count指出列表中attribute_info表的数量 |
attribute_info |
atrributes |
atrributes_count |
由多个attribute_info表组成的列表 |
field_info表中access_flags项的标志
标 志 名 称 |
值 |
设 定 含 义 |
设 定 者 |
ACC_PUBLIC |
0x0001 |
字段设为public |
类和接口 |
ACC_PRIVATE |
0x0002 |
字段设为private |
只有类 |
ACC_PROTECTED |
0x0004 |
字段设为protected |
只有类 |
ACC_STATIC |
0x0008 |
字段设为static |
类和接口 |
ACC_FINAL |
0x0010 |
字段设为final |
类和接口 |
ACC_VOLATILE |
0x0040 |
字段设为volatile |
只有类 |
ACC_TRANSIENT |
0x0080 |
字段设为transient |
只有类 |
method_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u2 |
access_flags |
1 |
见下方的表 |
u2 |
name_index |
1 |
提供了给出方法简单名称(不是全限定名)的CONSTANT_Utf8_info入口的索引 |
u2 |
descriptor_index |
1 |
提供了给出方法描述符的CONSTANT_Utf8_info入口的索引 |
u2 |
atrributes_count |
1 |
attributes_count指出列表中attribute_info表的数量 |
attribute_info |
atrributes |
atrributes_count |
由多个attribute_info表组成的列表 |
method_info表中access_flags项的标志
标 志 名 称 |
值 |
设 定 含 义 |
设 定 者 |
ACC_PUBLIC |
0x0001 |
方法设为public |
类和所有的接口方法 |
ACC_PRIVATE |
0x0002 |
方法设为private |
只有类 |
ACC_PROTECTED |
0x0004 |
方法设为protected |
只有类 |
ACC_STATIC |
0x0008 |
方法设为static |
只有类 |
ACC_FINAL |
0x0010 |
方法设为final |
只有类 |
ACC_SYNCHRONIZED |
0x0020 |
方法设为synchronized |
只有类 |
ACC_NATIVE |
0x0100 |
方法设为native |
只有类 |
ACC_ABSTRACT |
0x0400 |
方法设为abstract |
类和所有的接口方法 |
ACC_STRICT |
0x0800 |
方法设为strictFP |
类和接口的<clinit>方法 |
由规范定义的attribute_info表的类型
名 称 |
使 用 者 |
描 述 |
Code |
method_info |
方法的字节码和其他数据 |
ConstantValue |
field_info |
final变量的值 |
Deprecated |
field_info、method_info |
字段或者方法被禁用的指示符 |
Exceptions |
method_info |
方法可能抛出的可被检测的异常 |
InnerClasses |
ClassFile |
内部、外部类的列表 |
LineNumberTable |
Code_attribute |
方法的行号与字节码的映射 |
LocalVariableTable |
Code_attribute |
方法的局部变量的描述 |
SourceFile |
ClassFile |
源文件名 |
Synthetic |
field_info、method_info |
编译器产生的字段或者方法的指示符 |
加载和存储指令用于将数据从栈帧的局部变量表和操作数栈之间来回传输:
访问对象的字段或数组元素的指令也同样会与操作数栈传输数据。
上面所列举的指令助记符中,有一部分是以尖括号结尾的(例如 iload_<n>),这些指令助记符实际上是代表了一组指令(例如 iload_<n>,它代表了 iload_0、iload_1、iload_2 和 iload_3 这几条指令)。这几组指令都是某个带有一个操作数的通用指令(例如 iload)的特殊形式,对于这若干组特殊指令来说,它们表面上没有操作数,不需要进行取操作数的动作,但操作数都是在指令中隐含的。除此之外,他们的语义与原生的通用指令完全一致(例如 iload_0 的语义与操作数为 0 时的 iload 指令语义完全一致)。在尖括号之间的字母制定了指令隐含操作数的数据类型,<i>代表是 int 形数据,<l>代表 long 型,<f>代表 float 型,<d>代表 double型。在操作 byte、char 和 short 类型数据时,也用 int 类型表示。
这种指令表示方法,在整个《Java 虚拟机规范》之中都是通用的。
算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶。大体上运算指令可以分为两种:对整型数据进行运算的指令与对浮点型数据进行运算的指令,无论是那种算术指令,都是使用 Java 虚拟机的数字类型的。数据没有直接支持 byte、short、char 和 boolean 类型的算术指令,对于这些数据的运算,都是使用操作 int 类型的指令。
整数与浮点数的算术指令在溢出和被零除的时候也有各自不同的行为,所有的算术指令包括:
虽然类实例和数组都是对象,但 Java 虚拟机对类实例和数组的创建与操作使用了不同的字节码指令:
Java 虚拟机提供了一些用于直接操作操作数栈的指令,包括:pop、pop2、dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2 和 swap。
控制转移指令可以让 Java 虚拟机有条件或无条件地从指定指令而不是控制转移指令的下一条指令继续执行程序。控制转移指令包括有:
以下四条指令用于方法调用:
而方法返回指令则是根据返回值的类型区分的,包括有 ireturn(当返回值是 boolean、byte、char、short 和 int 类型时使用)、lreturn、freturn、dreturn 和 areturn,另外还有一条 return 指令供声明为 void 的方法、实例初始化方法、类和接口的类初始化方法使用。
在程序中显式抛出异常的操作会由 athrow 指令实现,除了这种情况,还有别的异常会在其它 Java 虚拟机指令检测到异常状况时由虚拟机自动抛出。
9、同步指令