switch
statements uses the tableswitch and lookupswitch instructions. The tableswitch instruction is used when the cases of the
switch
can be efficiently represented as indices into a table of target offsets. The
default
target of the
switch
is used if the value of the expression of the
switch
falls outside the range of valid indices. For instance,
compiles toint chooseNear(int i) {
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
}
The Java virtual machine's tableswitch and lookupswitch instructions operate only onMethodint
chooseNear(int)
0 iload_1 // Push local variable 1 (argumenti
)
1 tableswitch 0 to 2: // Valid indices are 0 through 2
0: 28 // Ifi
is0
, continue at 28
1: 30 // Ifi
is1
, continue at 30
2: 32 // Ifi
is2
, continue at 32
default:34 // Otherwise, continue at 34
28 iconst_0 //i
was0
; pushint
constant0
...
29 ireturn // ...and return it
30 iconst_1 //i
was1
; pushint
constant1
...
31 ireturn // ...and return it
32 iconst_2 //i
was2
; pushint
constant2
...
33 ireturn // ...and return it
34 iconst_m1 // otherwise pushint
constant -1
...
35 ireturn // ...and return it
int
data. Because operations on
byte
,
char
, or
short
values are internally promoted to
int
, a
switch
whose expression evaluates to one of those types is compiled as though it evaluated to type
int
. If the
chooseNear
method had been written using type
short
, the same Java virtual machine instructions would have been generated as when using type
int
. Other numeric types must be narrowed to type
int
for use in a
switch
.
Where the cases of the switch
are sparse, the table representation of the tableswitch instruction becomes inefficient in terms of space. The lookupswitch instruction may be used instead. The lookupswitch instruction pairs int
keys (the values of the case
labels) with target offsets in a table. When a lookupswitch instruction is executed, the value of the expression of the switch
is compared against the keys in the table. If one of the keys matches the value of the expression, execution continues at the associated target offset. If no key matches, execution continues at the default
target. For instance, the compiled code for
looks just like the code forint chooseFar(int i) {
switch (i) {
case -100: return -1;
case 0: return 0;
case 100: return 1;
default: return -1;
}
}
chooseNear
, except for the use of the lookupswitch instruction:
The Java virtual machine specifies that the table of the lookupswitch instruction must be sorted by key so that implementations may use searches more efficient than a linear scan. Even so, the lookupswitch instruction must search its keys for a match rather than simply perform a bounds check and index into a table like tableswitch. Thus, a tableswitch instruction is probably more efficient than a lookupswitch where space considerations permit a choice.Methodint
chooseFar(int)
0 iload_1
1 lookupswitch 3:
-100: 36
0: 38
100: 40
default:42
36 iconst_m1
37 ireturn
38 iconst_0
39 ireturn
40 iconst_1
41 ireturn
42 iconst_m1
43 ireturn