硬核万字长文,深入理解 Java 字节码指令(建议收藏) (6)

对于 double 和 float 来说,由于 NaN 的存在,有两个版本的比较指令。拿 float 来说,有 fcmpg 和 fcmpl,区别在于,如果遇到 NaN,fcmpg 会将 1 压入栈,fcmpl 会将 -1 压入栈。

举例来说。

public void lcmp(long a, long b) {
    if(a > b){}
}

通过 jclasslib 看一下 lcmp() 方法的字节码指令。

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

lcmp 用于两个 long 型的数据进行比较。

2)条件跳转指令

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

这些指令都会接收两个字节的操作数,它们的统一含义是,弹出栈顶元素,测试它是否满足某一条件,满足的话,跳转到对应位置。

对于 long、float 和 double 类型的条件分支比较,会先执行比较指令返回一个整形值到操作数栈中后再执行 int 类型的条件跳转指令。

对于 boolean、byte、char、short,以及 int,则直接使用条件跳转指令来完成。

举例来说。

public void fi() {
    int a = 0;
    if (a == 0) {
        a = 10;
    } else {
        a = 20;
    }
}

通过 jclasslib 看一下 fi() 方法的字节码指令。

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

3 ifne 12 (+9) 的意思是,如果栈顶的元素不等于 0,跳转到第 12(3+9)行 12 bipush 20。

3)比较条件转指令

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

前缀“if_”后,以字符“i”开头的指令针对 int 型整数进行操作,以字符“a”开头的指令表示对象的比较。

举例来说。

public void compare() {
    int i = 10;
    int j = 20;
    System.out.println(i > j);
}

通过 jclasslib 看一下 compare() 方法的字节码指令。

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

11 if_icmple 18 (+7) 的意思是,如果栈顶的两个 int 类型的数值比较的话,如果前者小于后者时跳转到第 18 行(11+7)。

4)多条件分支跳转指令

主要有 tableswitch 和 lookupswitch,前者要求多个条件分支值是连续的,它内部只存放起始值和终止值,以及若干个跳转偏移量,通过给定的操作数 index,可以立即定位到跳转偏移量位置,因此效率比较高;后者内部存放着各个离散的 case-offset 对,每次执行都要搜索全部的 case-offset 对,找到匹配的 case 值,并根据对应的 offset 计算跳转地址,因此效率较低。

举例来说。

public void switchTest(int select) {
    int num;
    switch (select) {
        case 1:
            num = 10;
            break;
        case 2:
        case 3:
            num = 30;
            break;
        default:
            num = 40;
    }
}

通过 jclasslib 看一下 switchTest() 方法的字节码指令。

硬核万字长文,深入理解 Java 字节码指令(建议收藏)

case 2 的时候没有 break,所以 case 2 和 case 3 是连续的,用的是 tableswitch。如果等于 1,跳转到 28 行;如果等于 2 和 3,跳转到 34 行,如果是 default,跳转到 40 行。

5)无条件跳转指令

goto 指令接收两个字节的操作数,共同组成一个带符号的整数,用于指定指令的偏移量,指令执行的目的就是跳转到偏移量给定的位置处。

前面的例子里都出现了 goto 的身影,也很好理解。如果指令的偏移量特别大,超出了两个字节的范围,可以使用指令 goto_w,接收 4 个字节的操作数。

巨人的肩膀:

https://segmentfault.com/a/1190000037628881

除了以上这些指令,还有异常处理指令和同步控制指令,我打算吊一吊大家的胃口,大家可以期待一波~~

(骚操作)

路漫漫其修远兮,吾将上下而求索

想要走得更远,Java 字节码这块就必须得硬碰硬地吃透,希望二哥的这些分享可以帮助到大家~

叨逼叨

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zggffx.html