一个class文件包含的是8字节流,所有16-bit、32-bit、64-bit的值都是以2个、4个、8个连接的字节组成。多字节的数据总是以大端的形式保存,也就是低字节在高内存地址。在Java SE平台上,支持这种形式有java.io.DataInput和java.io.DataOutput和实现类java.io.DataInputStream和java.io.DataOutputStream。
类形u1, u2, u4分别表示1、2、4字节变量,通过java.io.DataInput的readUnsignedByte、readUnsignedShort和readInt方法进行读取。
ClassFile的结构
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
(1)magic
魔数,用于指定这是class file格式,值为0xCAFEBABE。
(2)minor_version, major_verson
如果一个class文件major version M,minor version m,那么这个class file就被标识为M.m。一个Java虚拟机实现支持class file版本格式指定,这样只有在指定范围的class file才能加载。
(3)constant_pool_count/constant_pool[]
constant_pool表示各种字符串常量、类和接口名称、属性名称和其它常量。
(4)access_flags
表示类名名称的访问控制。
Flag Name | Value | Interpretation |
---|---|---|
ACC_PUBLIC | 0x0001 | Declared public ; may be accessed from outside its package. |
ACC_FINAL | 0x0010 | Declared final ; no subclasses allowed. |
ACC_SUPER | 0x0020 | Treat superclass methods specially when invoked by the invokespecial instruction. |
ACC_INTERFACE | 0x0200 | Is an interface, not a class. |
ACC_ABSTRACT | 0x0400 | Declared abstract ; must not be instantiated. |
ACC_SYNTHETIC | 0x1000 | Declared synthetic; not present in the source code. |
ACC_ANNOTATION | 0x2000 | Declared as an annotation type. |
ACC_ENUM | 0x4000 | Declared as an enum type. |
(5)this_class/super_class
这个值必须是constant_pool中有效的索引值。
(6)interfaces_count/interfaces[]
这些值必须是constant_pool中的索引
(7)field_count/fields[]
必须为field_info数据结构
(8)methods_count/methods[]
数据结构为method_info
(9)attributes_count/attributes[]
数据结构为attribute_info,这些attributes表示class file中的InnerClasses、EnclosingMethod、Synthetic、Signature、SourceFile、SourceDebugExtension、Deprecated、RuntimeVisibleAnnotations、RuntimeInvisibleAnnotations和BootstrapMethods。
名称的内部形式
1.二进制类和接口的名称
由于它们是以全限定的形式表示,所以名称总是表示为CONSTANCT_Utf8_info结构,由于历史原因,二进制名称表示在语法上不尽相同,这里使用/替代点。
2.非限定名
方法的名称、属性和局部变量被保存为非限定名,一个非限定名称不能包含ASCII字符(.;[/).
描述和签名
描述用于表示属性和方法的类型的字符串、签名是用于表示属性或方法的通用类型。
1.Field Descriptors
一个类、接口或局部变量的描述表示。
FieldDescriptor:
FieldType
FieldType:
BaseType
ObjectType
ArrayType
BaseType:
B
C
D
F
I
J
S
Z
ObjectType:
L ClassName ;
ArrayType:
[ ComponentType
ComponentType:
FieldType
BaseTypeCharacter | Type | Interpretation |
---|---|---|
B | byte | signed byte |
C | char | Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16 |
D | double | double-precision floating-point value |
F | float | single-precision floating-point value |
I | int | integer |
J | long | long integer |
L ClassName; | reference | an instance of class ClassName |
S | short | signed short |
Z | boolean | true or false |
[ | reference | one array dimension |
2.Method Descriptors
用于描述方法接收的参数的返回的值。
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
ParameterDescriptor:
FieldType
ReturnDescriptor:
FieldType
VoidDescriptor
VoidDescriptor:
V
参考:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3
最后欢迎大家访问我的个人网站:1024s