從字節碼層面,解析 Java 布爾型的實現原理


最近在系統回顧學習 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

這個 asmtools jar包的下載地址不是很好找,我這里啰嗦一下講講在哪里下載。打開上面的鏈接后可以看到下面的圖:

點擊紅色框框的release:

之后點擊下載 asmtools*.tar.gz 文件,解壓之后就能夠看到對應的 asmtools 文件了。

上面這行命令其實就是把字節碼文件反匯編一下,然后存在 Foo.jasm.1 文件里。我們打開 Foo.jasm.1 文件可以看到下面的內容:

其實這個文件就是一系列字節碼指令的集合,上面 main 方法中的字節碼指令我們可以分兩部分來看。

第一部分的字節碼指令是這樣的:

點擊圖片可以看到每一個字節碼指令的詳細解釋

其實這幾行的邏輯對應下面這塊源碼:

if(flag){
    System.out.println("Hello, Java!");
}

而第二部分的字節碼指令的分析:

點擊圖片可以看到每一個字節碼指令的詳細解釋

這幾行的邏輯對應下面這塊源碼:

if(flag == true){
    System.out.println("Hello, JVM!");
}

看完了這兩部分的字節碼指令,你會發現只有 iload_1 和 iconst_1 字節碼指令,而這兩個字節碼指令是對 int 類型數據的處理。所以我們可以知道,在 JVM 中 boolean 類型就是用 int 類型來存儲的。

其實還有一個方法可以很直觀地看出布爾型是使用整型表示的,那就是將 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 表示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM