Java - 条件跳转 switch


前言

探究 switch 语句在 JVM 里是如何执行的.

switch 语句

首先先写个 Java 代码

private static final Random random = new Random();

// ...

private static void statement() {
    int result;
    switch (random.nextInt(3)) {
        case 0: {
            result = 0;
            break;
        }
        case 1: {
            result = 1;
            break;
        }
        case 2: {
            result = 2;
            break;
        }
        default: {
            result = -1;
            break;
        }
    }
    System.out.println(result);
}

查看编译后字节码

pc bytecode
 0 getstatic #18 <xianzhan/java/base/lang/Switch.random>
 3 iconst_3
 4 invokevirtual #22 <java/util/Random.nextInt>
 7 tableswitch 0 to 2	
    0:  32 (+25)
	1:  37 (+30)
	2:  42 (+35)
	default:  47 (+40)
32 iconst_0
33 istore_0
34 goto 49 (+15)
37 iconst_1
38 istore_0
39 goto 49 (+10)
42 iconst_2
43 istore_0
44 goto 49 (+5)
47 iconst_m1
48 istore_0
49 getstatic #28 <java/lang/System.out>
52 iload_0
53 invokevirtual #34 <java/io/PrintStream.println>
56 return

根据上面字节码, 我们可以看到主要的字节码就是 tableswitch

tableswitch

tableswitch 用于 switch 条件跳转, 且 case 值连续(变长指令), 也就是执行完 case 代码块里的指令就会根据是否有 break 跳转到对应的字节码执行.

switch 表达式

JEP 325: Switch Expressions (Preview)
JEP 354: Switch Expressions (Second Preview)
JEP 361: Switch Expressions

switch 表达式在 JDK 12 中可以添加参数 --enable-preview 开启, 在 JDK 14 中已经成为正式不需要开启.

使用 switch 表达式简化上面写法

private static void expression() {
    int result = switch (random.nextInt(3)) {
        case 0 -> 0;
        case 1 -> 1;
        case 2 -> 2;
        default -> -1;
    };
    System.out.println(result);
}

查看字节码

pc bytecode
 0 getstatic #18 <xianzhan/java/base/lang/condition/Switch.random>
 3 iconst_3
 4 invokevirtual #22 <java/util/Random.nextInt>
 7 tableswitch 0 to 2	
    0:  32 (+25)
	1:  36 (+29)
	2:  40 (+33)
	default:  44 (+37)
32 iconst_0
33 goto 45 (+12)
36 iconst_1
37 goto 45 (+8)
40 iconst_2
41 goto 45 (+4)
44 iconst_m1
45 istore_0
46 getstatic #28 <java/lang/System.out>
49 iload_0
50 invokevirtual #34 <java/io/PrintStream.println>
53 return

当然, 如果 case 代码块有行语句, 那怎么返回呢? 这时我们可以使用新的关键字 yield

private static void mulExpression() {
    int result = switch (random.nextInt(3)) {
        case 0 -> {
            System.out.println(0);
            yield 0;
        }
        case 1 -> {
            System.out.println(1);
            yield 1;
        }
        case 2 -> {
            System.out.println(2);
            yield 2;
        }
        default -> {
            System.out.println("default");
            yield -1;
        }
    };
    System.out.println(result);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值