java編譯位元組碼
❶ 雲南電腦培訓分享位元組碼指令的編譯與執行
java編程開發是目前市場上使用范圍非常廣泛的一種編程開發語言。今天我們就一起來了解一下,在java編程中關於位元組碼的一些指令的編譯與執行方法。
java文件編譯後的class文件,java跨平台的中間層,JVM通過對位元組碼的解釋執行(執行模式,還有JIT編譯執行,下面講解),屏蔽對操作系統的依賴。一個位元組(8位)可以儲存256中不同的指令,這樣的指令就是位元組碼,java所有指令有200個左右,這些指令組成了位元組碼文件(.class)。
一、位元組碼的主要指令:
.class文件裡面的十六進制文件,其中CAFE BABE是標志這個文件為java的編譯後的文件,00000034代表版本號,01670700一個位元組(8位)就是一個位元組指令,由於數值指令太難看懂,我們可以用javap將指令翻譯為助記指令。
1、載入或儲存指令
在棧幀中,通過指令操作數據在局部變數表與操作棧間傳遞。
ILOAD、ALOAD:將int、對象引用類型從局部變數表壓入操作棧頂;
ISTORE、ASTORE:將int、對象引用類型從操作棧頂儲存到局部變數表裡;
ICONST、BIPUSH、SIPUSH、LDC:將常亮載入到操作棧頂。
2、運算指令
對操作棧上的值進行運算,並把結果寫入操作棧頂,如IADD、IMUL。
3、類型轉換指令
I2L、D2F
4、對象創建與訪問指令
NEW
除了位元組碼指令外,雲南電腦培訓http://www.kmbdqn.com/認為還包括像LINENUMBER儲存位元組碼與源碼對應,方便調試定位;LOCALVARIABLE儲存當前方法使用到的局部表量表。
二、java源碼文件轉化為位元組碼(.class)文件的過程
JAVA源文件---------->詞法解析---------->語法解析---------->語義分析--------->生成位元組碼--------->位元組碼文件
詞法分析:根據空格分割出單詞、操作符等,形成token信息流;
語法分析:根據token流和java語法規范生成語法樹;
語義分析:檢查關鍵字、類型匹配是否正確;
❷ Java 為什麼要編譯為位元組碼
眾所周知,java是跨平台的。
位元組碼文件可以看做是對機器碼的進一步抽象,
通過定義標準的位元組碼,jvm就只關心位元組碼,從而屏蔽從位元組碼到機器碼在不通操作系統底層的差異,這就實現了跨平台。
另外,在我們做性能調優的時候也可以通過查看位元組碼的表現來進一步修改自己的邏輯代碼。
❸ Java 為什麼要編譯為位元組碼
Java 最初設計的時候,跨平台就是一個重要的目標,所謂「一次編寫,到處運行」。而為了實現跨平台,就決定了不能像 c,c++ 那樣直接把源代碼編譯成可執行文件,因為不同cpu,不同操作系統的指令封裝格式是不一樣的。
而為了實現跨平台,一般有兩種方案,第一是直接執行源代碼,第二是像現在 Java 這樣編譯成一個中間格式文件,即 class 文件,這兩種方案各有優劣,現在說一下編譯成中間代碼的優點,class 文件相比較於 Java 源碼文件,有兩個優點:
class 文件內容設計的更加緊湊,方便 JVM 執行,也方便網路傳輸(最初 JAVA 的一個重要應用就是 applet,在當年網路不是很放大的年代,程序的體積還是要挺重要的)
方便其它語言執行。現在 JVM 上就有除了 Java 外大量的第三方語言,比如 scala,Clojure 等等。其它語言只要編譯成 class 文件即可像 Java 一樣在 JVM 上執行。
❹ java程序編譯後的位元組碼是怎麼轉換的
java編譯後的是位元組碼。 位元組碼,為java源代碼編譯完成後,由JVM轉換成的文件,可以在任何裝有JVM的系統上,轉化相應的機器語言。 機器碼:即機器語言,表示的就是運行位元組碼文件後的二進制序列。
❺ java如何生成位元組碼文件
java生成位元組碼文件全過程:
Java 源碼編譯由以下三個過程組成:
1、分析和輸入到符號表
2、註解處理
3、語義分析和生成class文件
流程圖如下所示:
最後生成的class文件由以下部分組成:
結構信息。包括class文件格式版本號及各部分的數量與大小的信息
元數據。對應於Java源碼中聲明與常量的信息。包含類/繼承的超類/實現的介面的聲明信息、域與方法聲明信息和常量池
方法信息。對應Java源碼中語句和表達式對應的信息。包含位元組碼、異常處理器表、求值棧與局部變數區大小、求值棧的類型記錄、調試符號信息
❻ 在java編程中用什麼命令來編譯java源文件 可以將源文件編譯成位元組碼文件,求答案 。
答案如下:
1 、javac 選 A
2、 int 選 D int 為關鍵字
3、 4 選 B
4、 15 選C
5 、界面類型 選D
6 、age[0] 選B
7、 class 選A
8 、java B
9、 abstract 選B
10 、false 選D
1、 錯,區分大小寫
2、 對
3 、錯,可以有多個
4 、錯 ,private 不可以被繼承 public可以繼承
5、 錯,private 不能繼承
6 、錯,java中可以重載函數
❼ java編譯器將源程序編譯生成的位元組碼是什麼
位元組是電腦里的數據量單位
位元組碼(Byte-code)是一種包含執行程序、由一序列 op 代碼/數據對組成的二進制文件。位元組碼是一種中間碼,它比機器碼更抽象。它經常被看作是包含一個執行程序的二進制文件,更像一個對象模型。位元組碼被這樣叫因為通常每個 opcode 是一位元組長,但是指令碼的長度是變化的。每個指令有從 0 到 255(或十六進制的: 00 到FF)的一位元組操作碼,被參數例如寄存器或內存地址跟隨。
在計算機中,數據只用0和1兩種表現形式,(這里只表示一個數據點,不是數字),一個0或者1佔一個「位」,而系統中規定8個位為一個位元組,用來表示常用的256個字母、符號、控制標記,其中用一個位來進行數據校驗,其他七個位用來記錄數據。
按計算機中的規定,一個英文的字元用一個位元組,(如,."':;avcAVC都佔用一個位元組),而一個漢字以及漢字的標點符號、字元都佔用兩個位元組,(如,。「」:;AVCavc他們就得佔用兩個位元組)。
另外,他們是沒有辦法比較的,只能講一個字元佔用一個位元組,N個字元佔用N個位元組。
K是千 M是兆 G是吉咖 T是太拉 8bit(位)=1Byte(位元組) 1024Byte(位元組)=1KB 1024KB=1MB 1024MB=1GB 1024GB=1TB
java中,位元組碼是CPU構架(JVM)的具有可移植性的機器語言
❽ 編譯一個java源程序文件,會產生多少個位元組碼文件
一般情況下一個Java文件代表一個類,在編譯時會產生一個位元組碼.class文件。
但是在Java中
一個源文件中可以包含多個類,但是只能有一個public類,其他的都成為內部類,這時編譯時會生成多個位元組碼文件。一個是那個public類也是該源文件名對應的.class
另一個就是public類名$內部類名.class
❾ 什麼是Java位元組碼
它是程序的一種低級表示,可以運行於Java虛擬機上。將程序抽象成位元組碼可以保證Java程序在各種設備上的運行
Java號稱是一門「一次編譯到處運行」的語言,從我們寫的java文件到通過編譯器編譯成java位元組碼文件(.class文件),這個過程是java編譯過程;而我們的java虛擬機執行的就是位元組碼文件。不論該位元組碼文件來自何方,由哪種編譯器編譯,甚至是手寫位元組碼文件,只要符合java虛擬機的規范,那麼它就能夠執行該位元組碼文件。
JAVA程序的運行
因為Java具有跨平台特性,為了實現這個特性Java執行在一台虛擬機上,這台虛擬機也就是JVM,Java通過JVM屏蔽了不同平台之間的差異,從而做到一次編譯到處執行。JVM位於Java編譯器和OS平台之間,Java編譯器只需面向JVM,生成JVM能理解的代碼,這個代碼即位元組碼,JVM再將位元組碼翻譯成真實機器所能理解的二進制機器碼。
位元組碼是怎麼產生的?
我們所編寫的程序都是.java格式,通常在執行的時候也許點擊一下eclipse的運行鍵就可以在控制台看到運行結果,但是也可以更酷一些,如果你裝了JDK,那就可以直接在以命令行的方式編譯運行你的.java文件,編譯後會形成.class文件,這個.class文件即位元組碼。
位元組碼怎麼解讀?
上圖是編譯好的位元組碼文件,即一堆16進制的位元組,如果使用IDE去打開,也許看到的是已經被反編譯的我們所熟悉的java代碼,但這才是純正的位元組碼
這里只介紹位元組碼由哪些部分組成, 具體的意思自行網路或者看文尾的連接, 有較為詳細的講解
上圖即位元組碼文件的組成部分, Class文件的結構不像XML等描述語言那樣鬆散自由。由於它沒有任何分隔符號,
所以,以上數據項無論是順序還是數量都是被嚴格限定的。哪個位元組代表什麼含義,長度是多少,先後順序如何,都不允許改變, 如上圖左側即每一部分規定的長度
魔數(Magic Number)
魔數是用來區分文件類型的一種標志,一般都是用文件的前幾個位元組來表示。
比如0XCAFE BABE表示的是class文件,那麼有人會問,文件類型可以通過文件名後綴來判斷啊?是的,但是文件名是可以修改的(包括後綴),那麼為了保證文件的安全性,將文件類型寫在文件內部來保證不被篡改。
至於為什麼是CAFE BABE估計大家也能猜到, 程序員與咖啡的不解之緣
版本號(Version)
版本號含主版本號和次版本號,都是各佔2個位元組。在此Demo種為0X0000 0033。其中前面的0000是次版本號,後面的0033是主版本號。通過進制轉換得到的是次版本號為0,主版本號為51。高版本的JDK能向下兼容以前版本的Class文件,但不能運行以後版本的Class文件,即使文件格式未發生任何變化. 這就是target參數的用處,可以在使用JDK 1.7編譯時指定-target 1.5
常量池(Constant Pool)
常量池是Class文件中的資源倉庫, 量池中主要存儲2大類常量:字面量和符號引用。字面量如文本字元串,java中聲明為final的常量值等等,而符號引用如類和介面的全局限定名,欄位的名稱和描述符,方法的名稱和描述符。常量池是一個表結構,在表的內容前有一個類型的計數器,表示常量池的長度
上面的表中描述了11中數據類型的結構,其實在jdk1.7之後又增加了3種(CONSTANT_MethodHandle_info,CONSTANT_MethodType_info以及CONSTANT_InvokeDynamic_info)。這樣算起來一共是14種
訪問標志(Access_Flag)
訪問標志信息包括該Class文件是類還是介面,是否被定義成public,是否是abstract,如果是類,是否被聲明成final。通過上面的源代碼,我們知道該文件是類並且是public。
0x 00 21:是0×0020和0×0001的並集。其中0×0020這個標志值涉及到位元組碼指令
類索引(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)
通過上邊位元組碼圖可以看到,這個介面有2+n個位元組,前兩個位元組表示的是介面數量,後面跟著就是介面的表。我們這個類沒有任何介面,所以應該是0000。果不其然,查找位元組碼文件得到的就是0000。
欄位表集合(fields)
欄位表用於描述類和介面中聲明的變數。這里的欄位包含了類級別變數以及實例變數,但是不包括方法內部聲明的局部變數。接下來就是2+n個欄位屬性。我們只有一個屬性a,所以應該是0001。查找文件果不其然是0001。
該區域含有欄位的訪問標志, 訪問許可權, 欄位的名稱索引, 欄位的描述符索引, 屬性表
描述符的作用就是用來描述欄位的數據類型、方法的參數列表和返回值。而屬性表就是為欄位表和方法表提供額外信息的表結構。對於欄位來說,此處如果將欄位聲明為一個static final msg = "aaa"的常量,則欄位後就會跟著一個屬性表,其中存在一項名為ConstantValue,指向常量池中的一個常量,值為的"aaa"。
方法(methods)
包含訪問標志表, 方法名索引 , 方法描述符索引, 屬性表數量,等
Attribute
0×0001 :同樣的,表示有1個Attributes了。
0x000f : #15(「SourceFile」)
0×0000 0002 attribute_length=2
0×0010 : sourcefile_index = #16(「Demo.java」)
SourceFile屬性用來記錄生成該Class文件的源碼文件名稱。