深入理解Java虚拟机读书笔记之:第6章 Java class文件
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值决定 |
|
- 文字字符串,如String对象。
- 被定义的类和接口的全限定名。
- 被定义的类的超类(如果有的话)的全限定名。
- 被定义的类和接口的父接口的全限定名。
- 由类或者接口声明的任意字段的简单名称和描述符。
- 由类或者接口声明的任意方法的简单名称和描述符。
- 任何引用的类和接口的全限定名。
- 任何引用的字段的简单名称和描述符。
- 任何引用的方法的简单名称和描述符。
- 与属性相关的字符串。
名 称 |
数 量 |
描 述 |
|
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表的索引 |
类 型 |
名 称 |
数 量 |
描 述 |
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 |
只有类 |
|
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 |
编译器产生的字段或者方法的指示符 |
attribute_info表的格式
类 型 |
名 称 |
数 量 |
描 述 |
u2 |
attribute_name_index |
1 |
给出了包含属性名称的CONSTANT_Utf8入口的常量池中的索引 |
u4 |
attribute_length |
1 |
给出了属性数据的长度(以字节计) |
u1 |
info |
attribute_length |
包含属性数据 |
- 一个class文件中只能包含一个类或者接口
- 尽管class文件与Java语言结构相关,但它并不一定必须与Java语言相关
- Java class文件是8位字节的二进制流
- 数据项按顺序存储
- 文件紧凑
- 多字节的项按照高位在前的格式存储
- 常量池至关重要,包含了与class文件中类和接口相关的常量