Javaの公式文書では説明しています。
スイッチは、バイト、ショート、CHAR、およびint型のプリミティブデータ型で動作します。また、列挙型、Stringクラス、およびいくつかの特別なクラスで動作するラップ特定のプリミティブ型:文字、バイト、ショート、整数
基本データ型でのバイト/文字
public class SwitchBasicTest {
private int switchByte(byte i) {
int ret;
switch (i) {
case 0:
ret = 10;
break;
case 1:
ret = 11;
break;
default:
ret = 0;
}
return ret;
}
private int switchChar(char i) {
int ret;
switch (i) {
case 0:
ret = 10;
break;
case 1:
ret = 11;
break;
case 'a':
ret = 20;
break;
case '写':
ret = 21;
break;
default:
ret = 0;
}
return ret;
}
}
复制代码
javap -vまたは逆コンパイルするために他のツールを使用してSwitchBasicTest.class
本明細書で使用されるように、IDEAプラグインjclasslib Bytecode viewer
逆コンパイル入手switchByte
方法バイトコード:
0 iload_1
1 lookupswitch 2
0: 28 (+27)
1: 34 (+33)
default: 40 (+39)
28 bipush 10
30 istore_2
31 goto 42 (+11)
34 bipush 11
36 istore_2
37 goto 42 (+5)
40 iconst_0
41 istore_2
42 iload_2
43 ireturn
复制代码
switchChar
メソッドのバイトコード:
0 iload_1
1 lookupswitch 4
0: 44 (+43)
1: 50 (+49)
97: 56 (+55)
20889: 62 (+61)
default: 68 (+67)
44 bipush 10
46 istore_2
47 goto 70 (+23)
50 bipush 11
52 istore_2
53 goto 70 (+17)
56 bipush 20
58 istore_2
59 goto 70 (+11)
62 bipush 21
64 istore_2
65 goto 70 (+5)
68 iconst_0
69 istore_2
70 iload_2
71 ireturn
复制代码
それがために知られているbyte
他の基本的なデータ型、switch
直接使用する整数の比較
- バイト、short値は直接全体転送することができます
- チャーは、かかる
unicode
コード値整数 - 整数およびその他の包装タイプ、コール
intValue
整数変数の値を得る方法を
文字列(バージョンJDK1.7以降)の役割の中で
public class SwitchBasicTest {
private int switchString(String i) {
int ret;
switch (i) {
case "0":
ret = 10;
break;
case "1":
ret = 11;
break;
case "a":
ret = 20;
break;
default:
ret = 0;
}
return ret;
}
}
复制代码
使用IDEAエディタ、.classファイルは、コード逆コンパイルを参照のファイルを開きます。
public class SwitchBasicTest {
private int switchString(String i) {
byte var4 = -1;
switch(i.hashCode()) {
case 48:
if (i.equals("0")) {
var4 = 0;
}
break;
case 49:
if (i.equals("1")) {
var4 = 1;
}
break;
case 97:
if (i.equals("a")) {
var4 = 2;
}
}
byte ret;
switch(var4) {
case 0:
ret = 10;
break;
case 1:
ret = 11;
break;
case 2:
ret = 20;
break;
default:
ret = 0;
}
return ret;
}
}
复制代码
得られコンパイルswitchString
バイトコードを:
0 aload_1
1 astore_3
2 iconst_m1
3 istore 4
5 aload_3
6 invokevirtual #8 <java/lang/String.hashCode>
9 lookupswitch 3
48: 44 (+35)
49: 59 (+50)
97: 74 (+65)
default: 86 (+77)
44 aload_3
45 ldc #9 <0>
47 invokevirtual #10 <java/lang/String.equals>
50 ifeq 86 (+36)
53 iconst_0
54 istore 4
56 goto 86 (+30)
59 aload_3
60 ldc #11 <1>
62 invokevirtual #10 <java/lang/String.equals>
65 ifeq 86 (+21)
68 iconst_1
69 istore 4
71 goto 86 (+15)
74 aload_3
75 ldc #12 <a>
77 invokevirtual #10 <java/lang/String.equals>
80 ifeq 86 (+6)
83 iconst_2
84 istore 4
86 iload 4
88 tableswitch 0 to 2
0: 116 (+28)
1: 122 (+34)
2: 128 (+40)
default: 134 (+46)
116 bipush 10
118 istore_2
119 goto 136 (+17)
122 bipush 11
124 istore_2
125 goto 136 (+11)
128 bipush 20
130 istore_2
131 goto 136 (+5)
134 iconst_0
135 istore_2
136 iload_2
137 ireturn
复制代码
私たちは見ることができるswitch
という効果をString
整数のための2つに分割最終switch
文、具体的な手順:
- 計算と比較したハッシュコード
- 同じハッシュコード、それがさらに使用されている場合
equals
、同じ文字列の内容を決定するために、二つの文字列のハッシュコードと同じ場合に処理
列挙の下で働きます
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN, WINTER
}
public class SwitchEnumTest {
private static int testSpring(SeasonEnum seasonEnum) {
int ret;
switch (seasonEnum) {
case AUTUMN:
ret = 1;
break;
case SPRING:
ret = 2;
break;
case SUMMER:
ret = 3;
break;
case WINTER:
ret = 4;
break;
default:
ret = 5;
}
return ret;
}
}
复制代码
逆コンパイル入手testSpring
方法バイトコード:
0 getstatic #6 <xx/SwitchEnumTest$1.$SwitchMap$xx$enumt$SeasonEnum>
3 aload_0
4 invokevirtual #7 <xx/enumt/SeasonEnum.ordinal>
7 iaload
8 tableswitch 1 to 4 1: 40 (+32)
2: 45 (+37)
3: 50 (+42)
4: 55 (+47)
default: 60 (+52)
40 iconst_1
41 istore_1
42 goto 62 (+20)
45 iconst_2
46 istore_1
47 goto 62 (+15)
50 iconst_3
51 istore_1
52 goto 62 (+10)
55 iconst_4
56 istore_1
57 goto 62 (+5)
60 iconst_5
61 istore_1
62 iload_1
63 ireturn
复制代码
あなたは見ることができます: 4 invokevirtual #7 <xx/enumt/SeasonEnum.ordinal>
つまり、switch
列挙に作用するとき、列挙が呼び出すordinal
メソッドをその最終的にint
値比較
lookupswitch和tableswitch
tableswitch
配列を使用すること添字のジャンプ先線で位置決めすることができますlookupswitch
キーと値との関係を維持するために、行数、であることがマッチを見つけるためにインデックスを比較することにより、一つのジャンプtableswitch
よりlookupswitch
優れた検索のパフォーマンスswitch
ステートメントcase
分岐条件値スパース、tableswitch
空間低使用手順は、この場合に使用することができるlookupswitch
命令
結論
switch
構文は、実際には整数パラメータに対してのみ有効ですbreak
バイトコードレベルで生成goto
文をcase
テープずにbreak
次回に直接case
論理switch
列挙に作用する実際の列挙使用するordinal
比較のための基礎として、メソッド戻り値switch
文字列場合、文字列に作用するhashcode
比較の基準としては、hashcode
同じがさらに使用されるequals
文字列の内容を比較します- Java仮想マシン仕様、Java仮想マシン
tableswitch
とlookupswitch
の命令が唯一のint型の条件をサポートし、それがswitch
サポートしていないlong
ロング