最近在系統回顧學習 Java 虛擬機方面的知識,其中想到一個很有意思的問題:布爾型在虛擬機中到底是什麼類型?
要想解答這個問題,我們看 JDK 的源碼是無法解決源碼的,我們必須深入到 class 文件中才能解決問題。於是他給出了這麼一道題:
public class Foo{
static boolean flag;
public static void main(String[] args){
flag = true;
if(flag){
System.out.println("Hello, Java!");
}
if(flag == true){
System.out.println("Hello, JVM!");
}
}
}
這道題很簡單,結果是輸出:
Hello, Java!
Hello, JVM!
但我們要深入到 class 文件中去看看 JVM 對於這段代碼,它到底是怎麼執行字節碼指令的。於是我們使用 javac 命令得到它的 class 字節碼文件:
javac Foo.java
字節碼文件都是十六進制的字符集合,我們一般可以用 javap 命令來實現反彙編工作。但這次我們使用另一個工具,即 asmtools。它是 OpenJDK 提供的另一個反彙編工具。
java -cp /path/to/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1
注:上面需要下載 asmtools 這個 Jar 包,下載地址:asmtools - Code Tools - OpenJDK Wiki
上面這行命令其實就是把字節碼文件反彙編一下,然後存在 Foo.jasm.1 文件裡。我們打開 Foo.jasm.1 文件可以看到下面的內容:
其實這個文件就是一系列字節碼指令的集合,上面 main 方法中的字節碼指令我們可以分兩部分來看。接下來我們一部分一部分來分析:
(放大圖片查看每個指令集的作用)
其實這幾行的邏輯對應下面這塊源碼:
if(flag){
System.out.println("Hello, Java!");
}
而第二部分的字節碼指令的分析:
(放大圖片查看每個指令集的作用)
這幾行的邏輯對應下面這塊源碼:
if(flag == true){
System.out.println("Hello, JVM!");
}
經過這麼一分析,你會發現在 Java 虛擬機中是不存在布爾值這一類型的,他們都被整型來替代了。
其實還有一個方法可以很直觀地看出布爾型是使用整型表示的,那就是將 Foo.jasm 文件恢復成 class 文件。運行下面的命令,將其恢復成 class 文件:
java -cp asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm
你會發現目錄下生成了一個 Foo.class 文件,我們使用 JD-GUI 工具打開它:
你會發現原來是布爾型的變量,現在變成了整型。原來的 true 現在是 1 了。
總結一下,其實布爾型在 Java 虛擬機是用整型表示的,true 用 1 表示,false 用 0 表示。
閱讀更多 慕課網 的文章