目錄
引言:都知道java的原始檔最後會被編譯成class檔案,class檔案的內容是位元組碼。為什麼java要編譯成位元組碼吶?我覺得最主要的原因是Java想要做到的跨平臺。只要有虛擬機器器,在任何平臺的表現都一樣的,遮蔽了系統層的不同,並且不像C,C++ 等語言編譯成和平臺相關的機器碼。同時也給其他的語言提供了在虛擬機器器執行的機會,只要是符合規範的class檔案,不管是什麼語言編譯出來的都可以。比如scala,kotlin等等。
原生的位元組碼看起來實在費勁,讓我想起了組合,記不住太多的指令,有沒有什麼好的方式能既學習下位元組碼,也不至於勸退吶。?idea 自帶的位元組碼工具能完美解決這個問題。怎麼用吶?
建立Java檔案,並且編譯後,選中檔案後,點view -> Show ByteCode。彈出位元組碼檔案。
首先看下java原始碼。一個非常簡單的只有一個屬性,兩個方法的類。
來吧,一起看下位元組碼這個損色。請快速的掃過,不必深究細節,因為下面我會一行一行的解釋。
// class version 52.0 (52)
// access flags 0x21
public class org/pdool/d20200923/GamWatcher {
// compiled from: GamWatcher.java
// access flags 0x0
I age
// access flags 0x1
public <init>()V
L0
LINENUMBER 6 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lorg/pdool/d20200923/GamWatcher; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x1
public getAge()I
L0
LINENUMBER 9 L0
ALOAD 0
GETFIELD org/pdool/d20200923/GamWatcher.age : I
IRETURN
L1
LOCALVARIABLE this Lorg/pdool/d20200923/GamWatcher; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x1
public setAge(I)V
L0
LINENUMBER 12 L0
ALOAD 0
ILOAD 1
PUTFIELD org/pdool/d20200923/GamWatcher.age : I
L1
LINENUMBER 13 L1
RETURN
L2
LOCALVARIABLE this Lorg/pdool/d20200923/GamWatcher; L0 L2 0
LOCALVARIABLE age I L0 L2 1
MAXSTACK = 2
MAXLOCALS = 2
}
可真嚇人,獨坐敬亭山,相看兩討厭,看不懂啊。下面一起讀一下。幾乎都註釋了,應該看得懂吧。
一個最簡單的位元組碼檔案就是這樣,看起來似乎不難,所有的單詞也都認識,大概猜一下也能理解。既然有概念了,下面就列舉一下,對著位元組碼讀一下也就大概懂了。
方法呼叫指令。
位元組碼指令很多,我們也沒必要全部都懂,都能記住,只要在需要檢視的時候能根據檔案讀明白,理解其中的含義,知道class的檔案結構,畢竟我們是面向開發,不是面向研究,知其然知其所以然夠了,不用花太多的精力在上面。加油哦。
寫文章不容易,求點贊轉發,關注我的公眾號【香菜聊遊戲】,說不定會有驚喜哦。