在軟件測試中淺談JAVA CLASS文件結構
從上圖中可以看到,一個 Java 類文件大致可以歸為 10 個項:
以下轉載自:http://edu.cryes.com/program/java/27962.html
Java文件結構用類似struct的描述如下:
ClassFile {
u4 magic; // 必須為: 0xCAFEBABE
u2 minor_version;
u2 major_version; //CLASS文件結構主次版本號 JAVA2支持45.0-46.0
u2 constant_pool_count; //記錄常量信息
cp_info constant_pool[constant_pool_count-1]; //計數從1開始
u2 access_flags; //class/interface訪問權限
u2 this_class; //指向constant_poll中的有效索引值
u2 super_class; //0或指向constant_poll中的有效索引值,對于interface必須為非0
u2 interfaces_count; //superinterfaces的個數
u2 interfaces[interfaces_count]; //計數[0,count-1) 對應constant_pool中的一個索引值
u2 fields_count;
field_info fields[fields_count]; //主要用于記錄class及實例中的變量
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
cp_info {
u1 tag;
u1 info[];
}
tag 意義如下:
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
此時cp_info分別對應結構變化為
1. CONSTANT_Class
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
2. CONSTANT_Fieldref
CONSTANT_Fieldref_info {
u1 tag;
u2 class_index; //constant_pool的索引,對應CONSTANT_Class_info
u2 name_and_type_index;//constant_pool的索引,對應CONSTANT_NameAndType_info
}
3. CONSTANT_Methodref
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
4. CONSTANT_InterfaceMethodref
CONSTANT_InterfaceMethodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
5. CONSTANT_String
CONSTANT_String_info {
u1 tag;
u2 string_index;
}
6. CONSTANT_Integer
CONSTANT_Integer_info {
u1 tag;
u4 bytes;
}
7. CONSTANT_Float
CONSTANT_Float_info {
u1 tag;
u4 bytes;
}
8. CONSTANT_Long
CONSTANT_Long_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
9. CONSTANT_Double
CONSTANT_Double_info {
u1 tag;
u4 high_bytes;
u4 low_bytes
}
10.CONSTANT_NameAndType
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
11.CONSTANT_Utf8
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
access_flags意義如下:
ACC_PUBLIC 0x0001
ACC_FINAL 0x0010
ACC_SUPER 0x0020
ACC_INTERFACE 0x0200
ACC_ABSTRACT 0x0400
如果是interface那么必須置ACC_INTERFACE,如果沒有置ACC_INTERFACE則定義的是一個類而非接口。
如果設置了ACC_INTERFACE,那么ACC_ABSTRACT位也必須被設置,當然也可以設置ACC_PUBLIC。
ACC_SUPER用以表明invokespecial語義,Sun公司老的JAVA編譯器沒有設置ACC_SUPER,并且老的JVM
忽略ACC_SUPER位,但新的編譯器應該實現invokespecial語義。
其他未指明的位保留將來使用,并且編譯器應當將其置為0,同時Java虛擬機應當忽略他們。
this_class: constant_pool中的索引值,指向的元素的cp_info等價為CONSTANT_Class_info
CONSTANT_Class_info {
u1 tag; //必須為CONSTANT_Class (7)
u2 name_index; //為指向constant_pool中的一個索引值
}
name_index :指向的元素的cp_info等價為CONSTANT_Utf8_info
CONSTANT_Utf8_info {
u1 tag; //必須為CONSTANT_Utf8 (1)
u2 length;
u1 bytes[length]; //Utf8編碼的字符串
}
field_info {
u2 access_flags; //訪問控制權
u2 name_index; //constant_pool中的索引,對應于CONSTANT_Utf8_info描述。
u2 descriptor_index; //constant_pool中的索引,對應于CONSTANT_Utf8_info描述。
u2 attributes_count;
attribute_info attributes[attributes_count]; //attribute_info將在mothods后描述。
}
field_info中access_flages意義如下:
ACC_PUBLIC 0x0001
ACC_PRIVATE 0x0002
ACC_PROTECTED 0x0004
ACC_STATIC 0x0008
ACC_FINAL 0x0010
ACC_VOLATILE 0x0040
ACC_TRANSIENT 0x0080
其中很顯然不能同時為ACC_FINAL和ACC_VOLATILE ;且前三項是互斥的。
interface必須置ACC_PUBLIC, ACC_STATIC,ACC_FINAL位,且不能置其他位。
其他未指明的位保留將來使用,并且編譯器應當將其置為0,同時Java虛擬機應當忽略他們。
methods指明了類中的所有方法。
method_info {
u2 access_flags;
u2 name_index; //指向constant_pool的入口,對應為CONSTANT_Utf8_info
u2 descriptor_index; //指向constant_pool的入口,對應為CONSTANT_Utf8_info
u2 attributes_count;
attribute_info attributes[attributes_count];
//此處只能出現Code、Exceptions、Synthetic、Deprecated四種類型的屬性
}
access_flags訪問權描述如下:
ACC_PUBLIC 0x0001
ACC_PRIVATE 0x0002
ACC_PROTECTED 0x0004
ACC_STATIC 0x0008
ACC_FINAL 0x0010
ACC_SYNCHRONIZED 0x0020
ACC_NATIVE 0x0100
ACC_ABSTRACT 0x0400
ACC_STRICT 0x0800
attribute_info {
u2 attribute_name_index; //constant_pool中的索引,對應于CONSTANT_Utf8_info描述。
u4 attribute_length;
u1 info[attribute_length];
}
現在已經預定義的屬性有:
1. SourceFile : attribute_info被替代為:
SourceFile_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 sourcefile_index; //指向constant_pool中的一個CONSTANT_Utf8_info 結構。
}
2. ConstantValue : attribute_info被替代為:
ConstantValue_attribute {
u2 attribute_name_index;
u4 attribute_length; //必須為2
u2 constantvalue_index;
}