Java 14中扩展的开关表达式,除了程序员/查看者的视觉清晰度外,开关表达式的需求尚不清楚。是-
参考:https://www.techgeeknext.com/java/java14-features
JDK-14版本:
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
JDK 14字节代码
0: iconst_1
1: istore_1
2: iload_1
3: tableswitch { // 1 to 7
1: 44
2: 44
3: 44
4: 49
5: 54
6: 54
7: 59
default: 64
}
44: bipush 6
46: goto 65
49: bipush 7
51: goto 65
54: bipush 8
56: goto 65
59: bipush 9
61: goto 65
64: iconst_0
65: istore_2
66: return
JDK-10码
int numLetters;
int day = 1;
switch (day) {
case 1:
case 2:
case 3:
numLetters = 6;
break;
case 4:
numLetters = 7;
break;
case 5:
case 6:
numLetters = 8;
break;
case 7:
numLetters = 9;
break;
default:
numLetters = 0;
}
JDK-10字节代码
0: iconst_1
1: istore_2
2: iload_2
3: tableswitch { // 1 to 7
1: 44
2: 44
3: 44
4: 50
5: 56
6: 56
7: 62
default: 68
}
44: bipush 6
46: istore_1
47: goto 70
50: bipush 7
52: istore_1
53: goto 70
56: bipush 8
58: istore_1
59: goto 70
62: bipush 9
64: istore_1
65: goto 70
68: iconst_0
69: istore_1
70: return
除了在块内的局部分配减少了JIT指令之外,对于基元没有太大区别。
[像switch
超过String
一样,字节码没有变化,因此没有必要。
虽然字节码是专门为编译Java源代码而设计的,但并没有相同的限制。另请参见Bytecode features not available in the Java language…
switch
表达式利用了以前的功能,该功能以前没有被普通Java代码使用,但是可以由自动代码生成器或编译器肯定地用于针对JVM的其他编程语言,从而可以将值推送到操作数栈的不同分支中。开关盒,在合并点之后使用。对于良好的旧switch
语句,您始终必须将值存储到局部变量中并在合并点之后加载它。
〈另一个普通Java代码未利用的功能,但与Java字节码可以正常使用的另一个功能是,通过仅在switch指令之前放置目标位置,来(使用)switch指令产生奇特的循环。谁知道将来的语言版本中是否会使用某些源代码功能……〉
但是无论是否使用中间局部变量,都没有太大关系。在优化程序将代码转换为SSA form之后,甚至在应用其他代码转换和优化之前,就消除了局部变量和操作数堆栈之间的所有传输。
这不排除在特定实现(版本)中对切换指令进行细微更改而导致的surprising performance differences。