Java 字节码技术解读

Java 字节码技术

Java中的字节码,英文名为bytecode,是Java代码编译后的中间代码格式。JVM需要读取并解析字节码才能执行相应的任务。

从技术人员的角度看

Java字节码是JVM的指令集。JVM加载字节码格式的class文件,校验之后通过JIT编译器转换为本地机器代码执行。简单说字节码就是我们编写的Java应用程序大夏的每一块砖,如果没有字节码的支撑,大家编写的代码也就没有了用武之地,无法运行。也可以说,Java字节码就是JVM执行的指令格式。

那么我们为什么需要掌握它呢?

不管用什么编程语言,对于卓越而有追求的程序员,都能深入去探索一些技术细节,在需要的时候,可以在代码被执行前解读和理解中间形式的代码。对于Java来说,中间代码格式就是Java字节码。理解字节码及其工作原理,对于编写高性能代码至关重要,对于深入分析和排查问题也有一定作用,所以我们要想深入了解JVM来捉,了解字节码也是必须掌握的基本功。同时,对于我们开发人员来说,不了解平台的底层原理和实现细节,想要职业进阶绝对不是长久之计,毕竟我们都希望成为更好的程序员,对吧?

Java字节码简介

Java bytecode由单字节(byte)的指令组成,理论上支持256个操作码。实际Java只使用了200左右的操作码,还有一些操作码则保留给调式操作。

根据指令的性质,主要分为四个大类:

1. 栈操作指令,包括与局部变量交互的指令
2. 程序流程控制指令
3. 对象操作指令,包括方法调用指令
4. 算数运算以及类型转换指令

此外还有一些执行专门任务的指令,比如同步(synchronization)指令,以及抛出异常相关的指令等等。

获取字节码清单

可以用javap工具来获取class文件中的指令清单。javap是标准JDK内置的一款工具,专门用于反编译class文件。

编写简单测试类:

package demo.jvm0104;

public class HelloByteCode {
    public static void main(String[] args) {
        HelloByteCode obj = new HelloByteCode();
    }
}

编译这个类:

javac demo/jvm0104/HelloByteCode.java

然后使用 javap 工具来执行反编译, 获取字节码清单:

javap -c demo.jvm0104.HelloByteCode
# 或者: 
javap -c demo/jvm0104/HelloByteCode
javap -c demo/jvm0104/HelloByteCode.class

javap 还是比较聪明的, 使用包名或者相对路径都可以反编译成功, 反编译后的结果如下所示:

Compiled from "HelloByteCode.java"
public class demo.jvm0104.HelloByteCode {
  public demo.jvm0104.HelloByteCode();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class demo/jvm0104/HelloByteCode
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: return
}
解读字节码清单

可以看到,反编译后的代码清单中,有一个默认的构造函数public demo.jvm0104.HelloByteCode(),以及main方法。

刚学Java时我们就知道,如果不定义任何构造函数,就会有一个默认的无参构造函数,这里再次验证了这个知识点。

再次回顾Java知识,每个构造函数中都会先调用super类的构造函数对吧?但这不是JVM自动执行的,而是由程序指令控制,所以默认构造函数中也就有一些字节码指令来干这个事情。

如:

  public demo.jvm0104.HelloByteCode();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

至于其中解析的java/lang/Object不用说,默认继承了Object类。这里再次验证了这个知识点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值