Java .class文件是什么?
Java class文件是什么?
?
java class 文件是對Java程序二進制文件格式的精確定義。每一個Java class文件都對一個Java類或者Java接口做出了全面描述。一個class文件中只能包含一個類或者接口。無論Java class文件在何種系統上產生,無論虛擬機在何種操作系統上運行,對Java class文件的精確定義使得所有Java虛擬機都能夠正確地讀取和解釋所有Java class文件。
盡管class文件與java語言結構相關,但它并不一定必須與Java程序相關。
如上圖所示:可以使用其他語言來編寫程序,然后將其編譯為class文件,或者把Java程序編譯為另一種不同的二進制文件格式。實際上,Java class文件的形式能夠表示Java源代碼中無法表達的有效程序,然而,絕大多數Java開發者幾乎都會選擇使用class文件作為傳遞給虛擬機的首要方式。Java class文件是八位字節的二進制流。數據項按順序存儲在class文件中,相鄰的項之間沒有任何間隔,這樣可以使得class文件緊湊。占據多個字節空間的想按照高位在前的順序分為幾個連續的字節存放。
和java的類可以包含多個不同的字段、方法、方法參數、局部變量等一樣,Java class文件也能夠包含許多不同大小的項。在class文件中,可變長度項的大小和長度位于其實際數據執之前。這個特性使得class文件流可以從頭到尾被順序解析,首先讀出項的大小,然后讀出項的數據。
?
?
Class文件的內容是什么?
?
Java class文件中包含了Java虛擬機所需知道的,關于類或接口的所有信息。
?
A class file consists of a single ClassFile structure:
?
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];
}
?
備注:u1 a single unsigned byte?
?u2 two unsigned bytes?
?u4 four unsigned bytes?
?u8 eight unsigned bytes?
?
- Magic Number: 0xCAFEBABE
- Version of Class File Format: the minor and major versions of the class file
- Constant Pool: Pool of constants for the class
- Access Flags: for example whether the class is abstract, static, etc
- This Class: The name of the current class
- Super Class: The name of the super class
- Interfaces: Any interfaces in the class
- Fields: Any fields in the class
- Methods: Any methods in the class
- Attributes: Any attributes of the class (for example the name of the sourcefile, etc)
ClassFile表中各項簡介如下:
(1)?magic(魔數)
每個Java class文件的錢四個字節被稱為他的魔數(magic number):0xCAFEBABE。魔數的做作用在于。可以輕松的分辨出Java class文件和非Java class文件,如果一個文件不是以0xCAFEBABE開頭,那它肯定不是java class文件。文件格式定義者能夠自由選擇魔數,前途是這個選中的魔數值沒有被廣泛應用。當java還被稱為“Oak”的時候,這個魔數就已經確定下來了。依照Patrick Naughton(最初Java開發小組的關鍵成員)的說法:“早在Java第一次作為該語言的名字發布前,我們就尋找一些好玩的、唯一的、容易記憶的東西。選擇0xCAFEBABE只不過是一個巧合,他象征著著名的咖啡品牌Peet's Coffee中最受歡迎的baristsa(一種咖啡的名稱),他預示著Java這個名字的出現”
?
(2)?minor_version和major_version
class文件的下面4個字節包含了主、次版本號。隨著Java技術的發展,Java class文件格式可能會加入新特性。class文件格式一旦發生變化,版本號也會隨之變化。對于Java虛擬機來說,版本號確定了特定的class文件格式,通常只有給定主版本號和一系列次版本號后,Java虛擬機才能夠讀取class文件。如果class文件的版本號超出了Java虛擬機所能處理的有效范圍,Java虛擬機將不會處理該class文件。
在Sun的JDK1.0.2發布版中,Java虛擬經濟實現支持從45.0(主版本號為45,次版本號為0)到45.3的class文件格式。在所有JDK1.1發布版本中虛擬機都能夠支持版本從450.到45.65535的class文件格式。在Sun的1.2版本的SDK中,虛擬機能夠支持從版本45.0到46.0的class文件格式。
。。。。。
?
(3)constant_pool_count和constant_pool
在class文件中,魔數和版本號后面的是常量池。在前面JVM的介紹中提到的http://boy00fly.iteye.com/blog/1095263,常量池中包含了與文件中類和接口相關的常量。常量池中存儲了諸如文字字符串、final變量值、類名和方法名的常量。Java虛擬機把常量池組織為入口列表的形式。在實際列表constant_pool之前,是入口在列表中的計數constant_pool_count.
常量池中的許多入口都指向其他的常量池入口,而class文件中緊隨這常量池的許多條目也會指向常量池中的入口。在整個class文件中,指示常量池入口在常量池列表中位置的整數索引都指向這些這些常量池入口。列表中的第一項索引值為1,第二項索引值為2,一次類推。盡管constant_pool列表中沒有索引值為0的入口,但缺失的這一入口也被constant_pool_count計數在內。例如:當constant_pool中有14項(索引值從1到14)時,constant_pool_count的值為15。
每個常量池入口都從一個長度為一個字節的標志開始,這個標志指出了列表中該位置的常量類型。一旦java虛擬機獲取并解析這個標志,Java虛擬機就會知道標志后的常量類型時什么。
?
?
Entry Type? Tag Value? Description
CONSTANT_Utf8? 1? A UTF-8 encoded Unicode string?
CONSTANT_Integer? ? ? ? ??3? An int literal value?
CONSTANT_Float? 4? A float literal value?
CONSTANT_Long? 5? A long literal value?
CONSTANT_Double? 6? A double literal value?
CONSTANT_Class? 7? A symbolic reference to a class or interface?
CONSTANT_String? 8 A String literal value?
CONSTANT_Fieldref? ? ? ? ? ? ? ? ??9? ? ? ? ? ??A symbolic reference to a field?
CONSTANT_Methodref? ? ? ? ?10? A symbolic reference to a method declared in a class?
CONSTANT_InterfaceMethodref? ? ? ? ?11 ?? ? ?? A symbolic reference to a method declared in an interface?
CONSTANT_NameAndType? ? ? ? ?12? Part of a symbolic reference to a field or method?
?
?
上面的每一個標志都有一個相對應的表,表明通過在標志名后加上"_info"后最來產生。例如:對應于CONSTANT_Class標志的表名為CONSTANT_Class_info,表名為CONSTANT_Utf8_info的表中存儲著Unicode字符串的壓縮形式。對應于各種不同的常量池入口的表,在后續章節中再闡述。
在動態連接的Java程序中,常量池充當了十分重要的角色。除了字面常量(或者說直接量)以外,常量池還可以容納下面幾種符號引用;
- 類和接口的全限定名
- 字段的名稱和描述符
- 方法的名稱和描述符
字段是類或接口的實例變量或者類變量。字段的描述符是一個指示字段的類型的字符串。
方法的描述符也是一個字符串,該字符串指示方法的返回值和參數的數量、順序和類型。
在運行時,Java虛擬機使用常量池的全限定名、方法和字段的描述符,把當前類或接口中的代碼與其他類或接口中的代碼連接起來。
由于class文件并不包含其內部組件最終內存布局的信息,因此類、字段和方法并不能被class文件中的字節碼直接引用。
java虛擬機從常量池獲得符號引用,然后再運行時解析引用項的實際地址。例如,用來調用方法的字節碼指令把一個符號引用的常量池所有傳給所調用的方法。
?
(4)?access_flags
緊接常量池后的兩個字節稱為access_flags,他展示了文件中定義的類或接口的幾段信息。例如,訪問標志指明文件中丁定義的是類還是接口;訪問表示還定義了在類或接口的聲明中使用了哪種修飾符;類和接口是抽象的,還是公共的;類的類型可以為final,而final類不可能是抽象的;接口不能為final類型。
(5)?this_class
接下來的兩個字節為this_class項,他是一個對常量池的索引。在this_class位置的常量池入口必須為CONSTANT_Class_info表。.....
?
(6)?super_class
在class文件中,緊接在this_class之后的是super_class項,他是一個兩個字節的常量池索引。在super_class位置的常量池入口是一個指向該類超類全限定名CONSTANT_Class_info.
?
(7)?interface_count和interface
緊接著super_class的是interface_count。此項的含義為:在文件中由該類直接實現或者由接口擴展的父接口的數量。在這個計數的后面,是名為interface的數組,他包含了對每個由該類或者接口直接實現的父接口的常量池索引。
?
(8)?fields_count和fields
緊接在interfaces后面的是對在該類或接口中所聲明的字段的描述。首先是名為fields_count的計數,他是類變量和實例變量的字段的數量總和。
在這個技術后面的是不同長度的field_info表的序列。
field的結構具有以下格式:
?
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
?
?
(9)?methods_count和methods
緊接在fields后面的是對在該類或接口中所聲明的方法的描述。
method的結構具有以下格式:
?
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
?
?
(10)?attributes_count和attributes
class文件中最后的部分是屬性(attribute),他給出了在該文件中類或接口鎖定義的屬性的基本信息。
attribute的結構具有以下格式:
?
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
總結
以上是生活随笔為你收集整理的Java .class文件是什么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 应用系统安全设计
- 下一篇: Java如何生成自己的微信二维码