它是程序的一種低級表示,可以運行于Java虛擬機上。將程序抽象成字節(jié)碼可以保證Java程序在各種設(shè)備上的運行
創(chuàng)新互聯(lián)基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)南充服務(wù)器托管報價,主機托管價格性價比高,為金融證券行業(yè)服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨享,G口帶寬及機柜租用的專業(yè)成都idc公司。
Java號稱是一門“一次編譯到處運行”的語言,從我們寫的java文件到通過編譯器編譯成java字節(jié)碼文件(.class文件),這個過程是java編譯過程;而我們的java虛擬機執(zhí)行的就是字節(jié)碼文件。不論該字節(jié)碼文件來自何方,由哪種編譯器編譯,甚至是手寫字節(jié)碼文件,只要符合java虛擬機的規(guī)范,那么它就能夠執(zhí)行該字節(jié)碼文件。
JAVA程序的運行
因為Java具有跨平臺特性,為了實現(xiàn)這個特性Java執(zhí)行在一臺虛擬機上,這臺虛擬機也就是JVM,Java通過JVM屏蔽了不同平臺之間的差異,從而做到一次編譯到處執(zhí)行。JVM位于Java編譯器和OS平臺之間,Java編譯器只需面向JVM,生成JVM能理解的代碼,這個代碼即字節(jié)碼,JVM再將字節(jié)碼翻譯成真實機器所能理解的二進制機器碼。
字節(jié)碼是怎么產(chǎn)生的?
我們所編寫的程序都是.java格式,通常在執(zhí)行的時候也許點擊一下eclipse的運行鍵就可以在控制臺看到運行結(jié)果,但是也可以更酷一些,如果你裝了JDK,那就可以直接在以命令行的方式編譯運行你的.java文件,編譯后會形成.class文件,這個.class文件即字節(jié)碼。
字節(jié)碼怎么解讀?
上圖是編譯好的字節(jié)碼文件,即一堆16進制的字節(jié),如果使用IDE去打開,也許看到的是已經(jīng)被反編譯的我們所熟悉的java代碼,但這才是純正的字節(jié)碼
這里只介紹字節(jié)碼由哪些部分組成, 具體的意思自行百度或者看文尾的連接, 有較為詳細(xì)的講解
上圖即字節(jié)碼文件的組成部分, Class文件的結(jié)構(gòu)不像XML等描述語言那樣松散自由。由于它沒有任何分隔符號,
所以,以上數(shù)據(jù)項無論是順序還是數(shù)量都是被嚴(yán)格限定的。哪個字節(jié)代表什么含義,長度是多少,先后順序如何,都不允許改變, 如上圖左側(cè)即每一部分規(guī)定的長度
魔數(shù)(Magic Number)
魔數(shù)是用來區(qū)分文件類型的一種標(biāo)志,一般都是用文件的前幾個字節(jié)來表示。
比如0XCAFE BABE表示的是class文件,那么有人會問,文件類型可以通過文件名后綴來判斷?。渴堑?,但是文件名是可以修改的(包括后綴),那么為了保證文件的安全性,將文件類型寫在文件內(nèi)部來保證不被篡改。
至于為什么是CAFE BABE估計大家也能猜到, 程序員與咖啡的不解之緣
版本號(Version)
版本號含主版本號和次版本號,都是各占2個字節(jié)。在此Demo種為0X0000 0033。其中前面的0000是次版本號,后面的0033是主版本號。通過進制轉(zhuǎn)換得到的是次版本號為0,主版本號為51。高版本的JDK能向下兼容以前版本的Class文件,但不能運行以后版本的Class文件,即使文件格式未發(fā)生任何變化. 這就是target參數(shù)的用處,可以在使用JDK 1.7編譯時指定-target 1.5
常量池(Constant Pool)
常量池是Class文件中的資源倉庫, 量池中主要存儲2大類常量:字面量和符號引用。字面量如文本字符串,java中聲明為final的常量值等等,而符號引用如類和接口的全局限定名,字段的名稱和描述符,方法的名稱和描述符。常量池是一個表結(jié)構(gòu),在表的內(nèi)容前有一個類型的計數(shù)器,表示常量池的長度
上面的表中描述了11中數(shù)據(jù)類型的結(jié)構(gòu),其實在jdk1.7之后又增加了3種(CONSTANT_MethodHandle_info,CONSTANT_MethodType_info以及CONSTANT_InvokeDynamic_info)。這樣算起來一共是14種
訪問標(biāo)志(Access_Flag)
訪問標(biāo)志信息包括該Class文件是類還是接口,是否被定義成public,是否是abstract,如果是類,是否被聲明成final。通過上面的源代碼,我們知道該文件是類并且是public。
0x 00 21:是0×0020和0×0001的并集。其中0×0020這個標(biāo)志值涉及到字節(jié)碼指令
類索引(This Class Name)
類索引用于確定類的全限定名
0×00 03 表示引用第3個常量,同時第3個常量引用第19個常量,查找得”com/demo/Demo”。#3.#19
父類索引(Super Class Name)
0×00 04 同理:#4.#20(java/lang/Object)
接口索引(Interfaces)
通過上邊字節(jié)碼圖可以看到,這個接口有2+n個字節(jié),前兩個字節(jié)表示的是接口數(shù)量,后面跟著就是接口的表。我們這個類沒有任何接口,所以應(yīng)該是0000。果不其然,查找字節(jié)碼文件得到的就是0000。
字段表集合(fields)
字段表用于描述類和接口中聲明的變量。這里的字段包含了類級別變量以及實例變量,但是不包括方法內(nèi)部聲明的局部變量。接下來就是2+n個字段屬性。我們只有一個屬性a,所以應(yīng)該是0001。查找文件果不其然是0001。
該區(qū)域含有字段的訪問標(biāo)志, 訪問權(quán)限, 字段的名稱索引, 字段的描述符索引, 屬性表
描述符的作用就是用來描述字段的數(shù)據(jù)類型、方法的參數(shù)列表和返回值。而屬性表就是為字段表和方法表提供額外信息的表結(jié)構(gòu)。對于字段來說,此處如果將字段聲明為一個static final msg = "aaa"的常量,則字段后就會跟著一個屬性表,其中存在一項名為ConstantValue,指向常量池中的一個常量,值為的"aaa"。
方法(methods)
包含訪問標(biāo)志表, 方法名索引 , 方法描述符索引, 屬性表數(shù)量,等
Attribute
0×0001 :同樣的,表示有1個Attributes了。
0x000f : #15(“SourceFile”)
0×0000 0002 attribute_length=2
0×0010 : sourcefile_index = #16(“Demo.java”)
SourceFile屬性用來記錄生成該Class文件的源碼文件名稱。
JAVA
程序編寫的源文件(源代碼)是以".java"為結(jié)尾的,JVM(JAVA虛擬機解析的文件)是以".class"為結(jié)尾的,".class"文件就是java的可執(zhí)行文件,同.exe文件具有同等的效果,.class文件采用的是魔力數(shù)字存儲,同時為了在不同的CPU下運行,規(guī)定了字節(jié)的保存形式,采用大端字節(jié)順序(BIG_ENDIAN)來保存的。而且".class"文件里面包含有編譯器的版本以及兼容性數(shù)據(jù)!
Java一般存在兩種文件格式,如下:
1.*.java文件是保存源代碼的文本文件
(*代表類名)
使用
javac
*.java可以編譯該文件
使用
java
*可以運行該類
2.*.class是用于保存
Java類的
二進制編碼以及Class對象,每一個
Java類都有一個解釋該類特征的
Class對象。*.jar文件
是一種壓縮文件格式
java源文件的格式是text/html類型的,可以直接用記事本打開。編碼可以是utf-8,也可以是其它類型的。后綴為.java
源文件編譯后的字節(jié)碼是以CAFE BABY開頭的二進制文件。需要JVM才能讀懂。后綴為.class
一般來說,一個類對應(yīng)一個字節(jié)碼文件,內(nèi)部類編譯后也會生成一個單獨的字節(jié)碼文件。字節(jié)碼文件是以類名來命名(標(biāo)識)的。
一些相關(guān)的字節(jié)碼文件可以按照包結(jié)構(gòu)打包成jar文件。jar文件和zip文件差不多。
java程序一般都會依賴很多的jar文件,比如最基本的rt.jar。
Java程序使用下列文件后綴:
文件類別
文件后綴
Java源文件
.java
Java字節(jié)碼文件
.class
2.2 常用文件名(CommonFile Names)
常用的文件名包括:
文件名?
用途
GNUmakefile? ??
makefiles的首選文件名。我們采用gnumake來創(chuàng)建(build)軟件。
README? ? ? ??
概述特定目錄下所含內(nèi)容的文件的首選文件名。
3. 文件組織(FileOrgnization)
一個文件由被空行分割而成的段落以及標(biāo)識每個段落的可選注釋共同組成。超過2000行的程序難以閱讀,應(yīng)該盡量避免?!癑ava源文件范例”提供了一個頁面布局合理的Java程序范例。
Java是Sun公司推出的一種編程語言。它是一種通過解釋方式來執(zhí)行的語言,語法規(guī)則和C++類似。同時,Java也是一種跨平臺的程序設(shè)計語言。用Java語言編寫的程序叫做“Applet”(小應(yīng)用程序),用編譯器將它編譯成類文件后,將它存在WWW頁面中,并在HTML檔上作好相應(yīng)標(biāo)記,用戶端只要裝上Java的客戶軟件就可以在網(wǎng)上直接運行“Applet”。 Java非常適合于企業(yè)網(wǎng)絡(luò)和Internet環(huán)境,現(xiàn)在已成為Internet中最受歡迎、最有影響的編程語言之一。 Java有許多值得稱道的優(yōu)點,如簡單、面向?qū)ο?、分布式、解釋性、可靠、安全、結(jié)構(gòu)中立性、可移植性、高性能、多線程、動態(tài)性等。Java擯棄了C++中各種弊大于利的功能和許多很少用到的功能。 Jave可以運行與任何微處理器,用Java開發(fā)的程序可以在網(wǎng)絡(luò)上傳輸,并運行于任何客戶機上。