Java .class文件是什么?
Java class文件是什么?
?
java class 文件是對(duì)Java程序二進(jìn)制文件格式的精確定義。每一個(gè)Java class文件都對(duì)一個(gè)Java類或者Java接口做出了全面描述。一個(gè)class文件中只能包含一個(gè)類或者接口。無論Java class文件在何種系統(tǒng)上產(chǎn)生,無論虛擬機(jī)在何種操作系統(tǒng)上運(yùn)行,對(duì)Java class文件的精確定義使得所有Java虛擬機(jī)都能夠正確地讀取和解釋所有Java class文件。
盡管class文件與java語言結(jié)構(gòu)相關(guān),但它并不一定必須與Java程序相關(guān)。
如上圖所示:可以使用其他語言來編寫程序,然后將其編譯為class文件,或者把Java程序編譯為另一種不同的二進(jìn)制文件格式。實(shí)際上,Java class文件的形式能夠表示Java源代碼中無法表達(dá)的有效程序,然而,絕大多數(shù)Java開發(fā)者幾乎都會(huì)選擇使用class文件作為傳遞給虛擬機(jī)的首要方式。Java class文件是八位字節(jié)的二進(jìn)制流。數(shù)據(jù)項(xiàng)按順序存儲(chǔ)在class文件中,相鄰的項(xiàng)之間沒有任何間隔,這樣可以使得class文件緊湊。占據(jù)多個(gè)字節(jié)空間的想按照高位在前的順序分為幾個(gè)連續(xù)的字節(jié)存放。
和java的類可以包含多個(gè)不同的字段、方法、方法參數(shù)、局部變量等一樣,Java class文件也能夠包含許多不同大小的項(xiàng)。在class文件中,可變長度項(xiàng)的大小和長度位于其實(shí)際數(shù)據(jù)執(zhí)之前。這個(gè)特性使得class文件流可以從頭到尾被順序解析,首先讀出項(xiàng)的大小,然后讀出項(xiàng)的數(shù)據(jù)。
?
?
Class文件的內(nèi)容是什么?
?
Java class文件中包含了Java虛擬機(jī)所需知道的,關(guān)于類或接口的所有信息。
?
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表中各項(xiàng)簡介如下:
(1)?magic(魔數(shù))
每個(gè)Java class文件的錢四個(gè)字節(jié)被稱為他的魔數(shù)(magic number):0xCAFEBABE。魔數(shù)的做作用在于。可以輕松的分辨出Java class文件和非Java class文件,如果一個(gè)文件不是以0xCAFEBABE開頭,那它肯定不是java class文件。文件格式定義者能夠自由選擇魔數(shù),前途是這個(gè)選中的魔數(shù)值沒有被廣泛應(yīng)用。當(dāng)java還被稱為“Oak”的時(shí)候,這個(gè)魔數(shù)就已經(jīng)確定下來了。依照Patrick Naughton(最初Java開發(fā)小組的關(guān)鍵成員)的說法:“早在Java第一次作為該語言的名字發(fā)布前,我們就尋找一些好玩的、唯一的、容易記憶的東西。選擇0xCAFEBABE只不過是一個(gè)巧合,他象征著著名的咖啡品牌Peet's Coffee中最受歡迎的baristsa(一種咖啡的名稱),他預(yù)示著Java這個(gè)名字的出現(xiàn)”
?
(2)?minor_version和major_version
class文件的下面4個(gè)字節(jié)包含了主、次版本號(hào)。隨著Java技術(shù)的發(fā)展,Java class文件格式可能會(huì)加入新特性。class文件格式一旦發(fā)生變化,版本號(hào)也會(huì)隨之變化。對(duì)于Java虛擬機(jī)來說,版本號(hào)確定了特定的class文件格式,通常只有給定主版本號(hào)和一系列次版本號(hào)后,Java虛擬機(jī)才能夠讀取class文件。如果class文件的版本號(hào)超出了Java虛擬機(jī)所能處理的有效范圍,Java虛擬機(jī)將不會(huì)處理該class文件。
在Sun的JDK1.0.2發(fā)布版中,Java虛擬經(jīng)濟(jì)實(shí)現(xiàn)支持從45.0(主版本號(hào)為45,次版本號(hào)為0)到45.3的class文件格式。在所有JDK1.1發(fā)布版本中虛擬機(jī)都能夠支持版本從450.到45.65535的class文件格式。在Sun的1.2版本的SDK中,虛擬機(jī)能夠支持從版本45.0到46.0的class文件格式。
。。。。。
?
(3)constant_pool_count和constant_pool
在class文件中,魔數(shù)和版本號(hào)后面的是常量池。在前面JVM的介紹中提到的http://boy00fly.iteye.com/blog/1095263,常量池中包含了與文件中類和接口相關(guān)的常量。常量池中存儲(chǔ)了諸如文字字符串、final變量值、類名和方法名的常量。Java虛擬機(jī)把常量池組織為入口列表的形式。在實(shí)際列表constant_pool之前,是入口在列表中的計(jì)數(shù)constant_pool_count.
常量池中的許多入口都指向其他的常量池入口,而class文件中緊隨這常量池的許多條目也會(huì)指向常量池中的入口。在整個(gè)class文件中,指示常量池入口在常量池列表中位置的整數(shù)索引都指向這些這些常量池入口。列表中的第一項(xiàng)索引值為1,第二項(xiàng)索引值為2,一次類推。盡管constant_pool列表中沒有索引值為0的入口,但缺失的這一入口也被constant_pool_count計(jì)數(shù)在內(nèi)。例如:當(dāng)constant_pool中有14項(xiàng)(索引值從1到14)時(shí),constant_pool_count的值為15。
每個(gè)常量池入口都從一個(gè)長度為一個(gè)字節(jié)的標(biāo)志開始,這個(gè)標(biāo)志指出了列表中該位置的常量類型。一旦java虛擬機(jī)獲取并解析這個(gè)標(biāo)志,Java虛擬機(jī)就會(huì)知道標(biāo)志后的常量類型時(shí)什么。
?
?
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?
?
?
上面的每一個(gè)標(biāo)志都有一個(gè)相對(duì)應(yīng)的表,表明通過在標(biāo)志名后加上"_info"后最來產(chǎn)生。例如:對(duì)應(yīng)于CONSTANT_Class標(biāo)志的表名為CONSTANT_Class_info,表名為CONSTANT_Utf8_info的表中存儲(chǔ)著Unicode字符串的壓縮形式。對(duì)應(yīng)于各種不同的常量池入口的表,在后續(xù)章節(jié)中再闡述。
在動(dòng)態(tài)連接的Java程序中,常量池充當(dāng)了十分重要的角色。除了字面常量(或者說直接量)以外,常量池還可以容納下面幾種符號(hào)引用;
- 類和接口的全限定名
- 字段的名稱和描述符
- 方法的名稱和描述符
字段是類或接口的實(shí)例變量或者類變量。字段的描述符是一個(gè)指示字段的類型的字符串。
方法的描述符也是一個(gè)字符串,該字符串指示方法的返回值和參數(shù)的數(shù)量、順序和類型。
在運(yùn)行時(shí),Java虛擬機(jī)使用常量池的全限定名、方法和字段的描述符,把當(dāng)前類或接口中的代碼與其他類或接口中的代碼連接起來。
由于class文件并不包含其內(nèi)部組件最終內(nèi)存布局的信息,因此類、字段和方法并不能被class文件中的字節(jié)碼直接引用。
java虛擬機(jī)從常量池獲得符號(hào)引用,然后再運(yùn)行時(shí)解析引用項(xiàng)的實(shí)際地址。例如,用來調(diào)用方法的字節(jié)碼指令把一個(gè)符號(hào)引用的常量池所有傳給所調(diào)用的方法。
?
(4)?access_flags
緊接常量池后的兩個(gè)字節(jié)稱為access_flags,他展示了文件中定義的類或接口的幾段信息。例如,訪問標(biāo)志指明文件中丁定義的是類還是接口;訪問表示還定義了在類或接口的聲明中使用了哪種修飾符;類和接口是抽象的,還是公共的;類的類型可以為final,而final類不可能是抽象的;接口不能為final類型。
(5)?this_class
接下來的兩個(gè)字節(jié)為this_class項(xiàng),他是一個(gè)對(duì)常量池的索引。在this_class位置的常量池入口必須為CONSTANT_Class_info表。.....
?
(6)?super_class
在class文件中,緊接在this_class之后的是super_class項(xiàng),他是一個(gè)兩個(gè)字節(jié)的常量池索引。在super_class位置的常量池入口是一個(gè)指向該類超類全限定名CONSTANT_Class_info.
?
(7)?interface_count和interface
緊接著super_class的是interface_count。此項(xiàng)的含義為:在文件中由該類直接實(shí)現(xiàn)或者由接口擴(kuò)展的父接口的數(shù)量。在這個(gè)計(jì)數(shù)的后面,是名為interface的數(shù)組,他包含了對(duì)每個(gè)由該類或者接口直接實(shí)現(xiàn)的父接口的常量池索引。
?
(8)?fields_count和fields
緊接在interfaces后面的是對(duì)在該類或接口中所聲明的字段的描述。首先是名為fields_count的計(jì)數(shù),他是類變量和實(shí)例變量的字段的數(shù)量總和。
在這個(gè)技術(shù)后面的是不同長度的field_info表的序列。
field的結(jié)構(gòu)具有以下格式:
?
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
?
?
(9)?methods_count和methods
緊接在fields后面的是對(duì)在該類或接口中所聲明的方法的描述。
method的結(jié)構(gòu)具有以下格式:
?
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的結(jié)構(gòu)具有以下格式:
?
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
總結(jié)
以上是生活随笔為你收集整理的Java .class文件是什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 应用系统安全设计
- 下一篇: Java如何生成自己的微信二维码