定义入栈java_小师妹学JVM之:java的字节码byte code简介
簡(jiǎn)介
Byte Code也叫做字節(jié)碼,是連接java源代碼和JVM的橋梁,源代碼編譯成為字節(jié)碼,而字節(jié)碼又被加載進(jìn)JVM中運(yùn)行。字節(jié)碼怎么生成,怎么查看字節(jié)碼,隱藏在Byte Code背后的秘密是什么呢?快跟小師妹一起來(lái)看看吧。
Byte Code的作用
小師妹:F師兄,為什么Java需要字節(jié)碼呢?直接編譯成為機(jī)器碼不是更快嗎?
小師妹,Java的設(shè)計(jì)初衷是一次編寫(xiě),到處運(yùn)行。為了兼容各個(gè)平臺(tái)的運(yùn)行環(huán)境,java特別為各種平臺(tái)設(shè)計(jì)了JVM。
我們可以把JVM看做是一種抽象,對(duì)外提供了統(tǒng)一的接口。這樣我們只需要編寫(xiě)符合JVM規(guī)范的代碼,即可在JVM中運(yùn)行。
回想下之前我們提到過(guò)的java的執(zhí)行過(guò)程:
小師妹:F師兄,我有一個(gè)大膽的想法,JVM的作用是將字節(jié)碼解釋或者編譯成為機(jī)器碼。然后在相應(yīng)的運(yùn)行環(huán)境中執(zhí)行。那么有沒(méi)有可能,不需要JVM,不需要機(jī)器碼,而是直接在對(duì)應(yīng)的平臺(tái)上執(zhí)行字節(jié)碼呢?
愛(ài)因斯坦說(shuō)過(guò)沒(méi)有想像力的靈魂,就像沒(méi)有望遠(yuǎn)鏡的天文臺(tái)。小師妹你這個(gè)想法很好,這種實(shí)現(xiàn)有個(gè)專(zhuān)業(yè)的說(shuō)法叫做:Java processor。
Java processor就是用硬件來(lái)實(shí)現(xiàn)的JVM。因此字節(jié)碼可以直接在Java processor中運(yùn)行。
其中比較出名的是Jazelle DBX,這是一個(gè)主要支持J2ME環(huán)境的硬件架構(gòu)。為了提升java在手機(jī)端的執(zhí)行速度。
但是這樣做其實(shí)也是有缺點(diǎn)的,后面我們會(huì)講到,java字節(jié)碼中的指令非常非常多。所以如果用硬件來(lái)實(shí)現(xiàn)的話(huà),就會(huì)非常非常復(fù)雜。
一般來(lái)說(shuō)Java processor不會(huì)實(shí)現(xiàn)全部的字節(jié)碼中的功能,只會(huì)提供部分的實(shí)現(xiàn)。
查看Byte Code字節(jié)碼
小師妹:F師兄,那使用javac編譯過(guò)后的class文件跟字節(jié)碼有什么關(guān)系呢?
class文件中大部分都是byte code,其他的部分是一些meta data元數(shù)據(jù)信息。這些組合在一起就是class文件了。
小師妹:F師兄,你說(shuō)class文件是byte code,為什么我在IDE中打開(kāi)的時(shí)候,直接顯示的是反編譯出來(lái)的源文件呢?
小師妹,這是IDE的一個(gè)便利功能。因?yàn)榇蠖鄶?shù)情況下,沒(méi)有人想去看class文件的Byte code的,大家都是想去看看這個(gè)class文件的源文件是什么樣的。
我們舉個(gè)最簡(jiǎn)單的例子:
這個(gè)類(lèi)中,我們定義了一個(gè)很簡(jiǎn)單的testByteCode方法,里面定義了兩個(gè)變量,然后返回他們兩個(gè)的和。
現(xiàn)在有兩種方法來(lái)查看這個(gè)類(lèi)的Byte Code:
第一種方法是用javap命令:
javap -c ByteCodeUsage.class生成的結(jié)果如上所示。
第二種方法就是在IDEA中,選中class文件,然后在view中選中show Bytecode:
我們看下輸出結(jié)果:
兩個(gè)的結(jié)果在顯示上面可能有細(xì)微的差異,但是并不影響我們后面對(duì)其的解析。
java Byte Code是怎么工作的
小師妹:F師兄,能講解一下這些byte code到底是怎么工作的嗎?
首先我們要介紹一下JVM的實(shí)現(xiàn)是基于棧的結(jié)構(gòu)的。為什么要基于棧的結(jié)構(gòu)呢?那是因?yàn)闂J亲钸m合用來(lái)實(shí)現(xiàn)function互相調(diào)用的。
我們?cè)倩仡櫼幌律厦娴膖estByteCode的字節(jié)碼。里面有很多iconst,istore的東西,這些東西被稱(chēng)作Opcode,也就是一些基于棧的操作指令。
上面講了java bytecode的操作指令其實(shí)有很多個(gè)。下面我們列出這些指令的部分介紹:
實(shí)在是太多了,這里就不把所有的列出來(lái)了。
我們看到的指令名字其實(shí)是一個(gè)助記詞,真實(shí)的Opcode是一個(gè)占用兩個(gè)字節(jié)的數(shù)字。
下面我們來(lái)詳細(xì)解釋一下testByteCode方法:
public int testByteCode();Code:0: iconst_11: istore_12: iconst_23: istore_24: iload_15: iload_26: iadd7: ireturn第一步,iconst_1將int 1加載到stack中。
第二步,istore_1將入棧的int 1出棧,并存儲(chǔ)到變量1中。
第三步,iconst_2將int 2入棧。
第四步,istore_2將入棧的int 2出棧,并存儲(chǔ)到變量2中。
第五步,iload_1將變量1中的值入棧。
第六步,iload_2將變量2中的值入棧。
第七步,iadd將棧中的兩個(gè)變量出棧,并相加。然后將結(jié)果入棧。
第八步,ireturn將棧中的結(jié)果出棧。
這幾步實(shí)際上完美的還原了我們?cè)趖estByteCode方法中定義的功能。
當(dāng)然我們只介紹了最賤的byte code命令,通過(guò)這些簡(jiǎn)單的命令可以組合成為更加復(fù)雜的java命令。
總結(jié)
本文介紹了java byte code的作用和具體的指令,并分析了一個(gè)簡(jiǎn)單的例子來(lái)做說(shuō)明。希望大家能夠掌握。
本文的例子https://github.com/ddean2009/learn-java-base-9-to-20
本文作者:flydean程序那些事本文鏈接:http://www.flydean.com/jvm-byte-code/本文來(lái)源:flydean的博客歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!總結(jié)
以上是生活随笔為你收集整理的定义入栈java_小师妹学JVM之:java的字节码byte code简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 纯净安装,微软 Win11 Dev Bu
- 下一篇: finalshell日志乱码问题_Tom