专栏首页陈树义从字节码层面,解析 Java 布尔型的实现原理

从字节码层面,解析 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 表示。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从抖音关闭评论,看服务治理的重要性

    4月10日,广电总局责令今日头条永久关停「内涵段子」等低俗视听产品。 该消息传出后,大量内涵段子用户涌入抖音,以统一头像和内涵段子风格的评论迅速占领抖音热门视频...

    陈树义
  • Java并发编程:synchronized

    Java并发编程:synchronized   虽然多线程编程极大地提高了效率,但是也会带来一定的隐患。比如说两个线程同时往一个数据库表中插入不重复的数据,就可...

    陈树义
  • 集合系列 List(三):Vector

    Vector 的底层实现以及结构与 ArrayList 完全相同,只是在某一些细节上会有所不同。这些细节主要有:

    陈树义
  • C++核心准则C.167:为具有约定俗成​语义的操作使用运算符

    Readability. Convention. Reusability. Support for generic code。

    面向对象思考
  • 小记两个问题

    同城异地灾备,业务双活,其实也不过就是看看是否需要SLB或者GSLB或者DNS,在进行灾备的时候,最主要的还是DNS服务的提供,在进行切换的时候,大部分...

    SRE运维实践
  • 零基础入门必备的Linux命令和C语言基础

      touch -t 0712250000 file1 修改一个文件或目录的时间戳 - (YYMMDDhhmm)

    用户6754675
  • (转载)常用shell命令

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecod...

    solve
  • 更多的常用命令

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecod...

    爱学习的孙小白
  • Linux入门所必备的Linux命令和C语言基础

    touch -t 0712250000 file1 修改一个文件或目录的时间戳 - (YYMMDDhhmm)

    用户6754675
  • 玩转linux 这些命令就够了

    现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。

    互扯程序

扫码关注云+社区

领取腾讯云代金券