环境
AdoptOpenJDK 15
IDEA
前言
探究 Java 语言条件判断 if 的实现
if
首先, 我们先写一个 if 语句
private static boolean b;
// ...
private static void ifMethod() {
if (b) {
System.out.println(b);
}
}
查看它编译后的字节码
pc bytecode
0 getstatic #14 <xianzhan/java/base/lang/IfElse.b> // 将 b 放入栈帧
3 ifeq 15 (+12) // 如果 ifeq 则直接到 return
6 getstatic #29 <java/lang/System.out>
9 getstatic #14 <xianzhan/java/base/lang/IfElse.b>
12 invokevirtual #35 <java/io/PrintStream.println>
15 return
从上面字节码中可以发现, 如果 ifeq
那就直接 return
, 也就是退出方法
ifeq
ifeq 字节码的作用:
ifeq 指令是类型安全的,前提是可以有效地将与 int 匹配的类型从传入的操作数堆栈中弹出,从而产生传出类型状态 NextStackFrame,并且该指令的操作数 Target 是假定 NextStackFrame 的传入类型状态的有效分支目标。
描述
它从操作数栈中弹出,并与零进行比较。如果栈里弹出的值是 0, 则
ifeq
成功。
从代码逻辑来看, 也就是说, false
的值在操作数栈里应该为 0
, 那么该如何去获取 false
的数值呢?
Field bField = IfElse.class.getDeclaredField("b");
bField.setAccessible(true);
long bAddr = Unsafe.staticFieldOffset(bField);
System.out.println(b + " is " + Unsafe.getInt(IfElse.class, bAddr));
执行上面代码, 我们会得到
false is 0
总结
也就是说, 当 b 为 false
时, 会将 pc (程序计数器) 的值修改为 15, 则下一条执行语句就是 return
, 退出方法了.