Java虛擬機器(一)-Java的class檔案詳解__Java

來源:互聯網
上載者:User
        java語言是跨平台的,所謂一次編寫,到處運行。之所以是跨平台的,就是 java定義了一套與作業系統,硬體無關的位元組碼格式,這個位元組碼就是用 java class檔案來表示的, java class檔案內部定義了虛擬機器可以識別的位元組碼格式,這個格式是平台無關性的,在 linux系統或者在 windows系統上都是一致的。這個就好比 html檔案,我們定義好規範,這個系統只要去按照規範顯示出來裡面的內容就好了。好比 html就是 class檔案,瀏覽器就是虛擬機器一樣,通過瀏覽器去執行 html的渲染過程,我們無論是用手機, Windows系統,蘋果系統上網,顯示出來的內容都是一樣。 java虛擬機器可以從 class檔案中載入預定義的位元組碼,也可以從網路,資料庫,訊息檔案中載入位元組碼。

如今的java虛擬機器已經稱為一種通用平台,不但能夠運行java語言,Groovy,JRuby,Jython等一大批動態語言也可以直接在Java虛擬機器上運行,其原理也是這些動態語言的編譯器將源碼檔案編譯為和Java相同的位元組碼檔案,這樣Java虛擬機器就可以像執行java語言一樣執行這些動態語言了。

位元組碼class類檔案是由一系列位元組碼命令組成,用於表示程式中各種常量、變數、關鍵字和運算子號的語義等等。

Java的Class類檔案是一組以8為位元組為單位的二進位流,各個資料項目嚴格按照順序緊湊地排列在Class類檔案之中,中間沒有添加任何分隔字元,

當遇到需要佔用8位位元組以上空間的資料項目時,按照高位在前的方式分割成若干個8位位元組進行儲存。

Java虛擬機器規定,Class類檔案格式採用類似C語言結構體的偽結構來儲存,這種偽結構中只有兩種資料類型:無符號數和表:

(1).無符號數:

屬於基本類型的資料,以u1, u2, u4, u8來分別代表1個位元組,2個位元組,4個位元組和8個位元組的無符號數,無符號數可以用來描述數字、索引引用、數量值或者按照UTF-8編碼的字串值。

(2).表:

由多個無符號數或其他表作為資料項目構成的複合資料型別,所以表都習慣性地以“_info“結尾。表用於描述有層次關係的複合結構資料,整個Class檔案本質就是一張表。

Java Class類檔案結構如下:

類型

名稱

數量

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

Class類檔案沒有任何分隔字元,是嚴格按照這個結構表順序排列,下面具體介紹各個名稱含義:

(1).magic:

每個Class檔案的頭4個位元組被稱為魔數,它的唯一作用是用於確定這個檔案是否為一個能被java虛擬機器所接收的Class類檔案,即用於判定檔案是否是符合規範的java Class檔案。雖然說尾碼名“.class”可以表明檔案是一個Class檔案,但是檔案尾碼名是可以隨意被改動的,基於安全的考慮,很多檔案都通過魔數值來唯一確定檔案類型,java的Class檔案魔數是:0xCAFEBABE.

(2).minor_version和major_version:

每個Class檔案的第5和第6個位元組代表Class檔案的次版本號碼,第7和第8個位元組代表Class檔案的主要版本號。Class檔案的主、次版本號碼是由JDK決定的,JDK1.0~JDK1.1使用了45.0~45.3的版本號碼(45是主要版本好,點”.“之後的是次版本號碼),從JDK1.1開始,每個大版本的JDK主要版本號加1.

Class主、次版本號碼的一個作用時,高版本的Java虛擬機器可以向前相容,運行低版本JDK編譯的Class位元組碼檔案,而低版本的java虛擬機器不能運行高版本JDK編譯的Class位元組碼檔案。當低版本的java虛擬機器運行高版本JDK編譯的Class位元組碼檔案時,通常會報類似如下的異常:

1. Exception in thread "main" java.lang.UnsupportedClassVersionError: a (Unsupporte 
2. d major.minor version 49.0)

JDK1.0~JDK1.1使用了45.0~45.3的版本號碼,JDK1.2使用了46.0~46.65535的版本號碼,JDK1.3使用了47.0~47.65535的版本號碼,JDK1.4使用了48.0~48.65535的版本號碼,JDK1.5使用了49.0~49.65535的版本號碼,JDK1.6使用了50.0~50.65535的版本號碼,JDK1.7使用51.0~51.65535的版本號碼。

在編譯時間可以通過指定-target參數來改變主要版本號,如JDK1.6編譯時間如果沒有給定target參數,則編譯出來的Class檔案的主要版本號是50,如果給定”-target 1.4 -source 1.4”參數之後,則主要版本將變為48,如果給定”-target 1.5 ”參數之後,則主要版本將變為49。

(3). constant_pool_count和constant_pool:

constant_pool_count代表Class檔案中常量池的數目,由於常量池的計數從1開始,因此常量池的容量是constant_pool_count-1。

第0項常量空出做特殊考慮,為了滿足一些指向常量池的索引值在某些特定情況下需要表達“不指向任何一個常量池”的意思。

constant_pool常量池是Class類檔案中出現的第一個表類型資料,常量池主要存放兩大類常量:

a.字面量(Literal):包括文本字串、final類型常量值。

b.符號引用(SymbolicReferences):包括類和介面的全限定名、欄位的名稱和描述符、方法的名稱和描述符。

(4). access_flags:用於表示Class或介面層次的訪問標誌,即類或介面層面的存取控制資訊,通常儲存的資訊包括:Class類檔案是類、介面、枚舉或是註解;是否定義為public類型;是否定義為abstract類型;類是否被定義為final等等。

(5). this_class、super_class和interfaces:this_class類索引用於確定類的全限定名,super_class父類索引用於確定父類的全限定名,interfaces介面索引用於確定介面的全限定名,由於java中可以實現多個介面,因此使用interfaces_count來儲存介面數量。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.