Pergantian pernyataan dengan String
kasus telah diimplementasikan di Java SE 7 , setidaknya 16 tahun setelah mereka pertama kali diminta. Alasan yang jelas untuk keterlambatan itu tidak disediakan, tetapi kemungkinan itu ada hubungannya dengan kinerja.
Implementasi di JDK 7
Fitur ini sekarang telah diimplementasikan javac
dengan proses "de-sugaring"; sintaks tingkat tinggi yang bersih menggunakan String
konstanta dalam case
deklarasi diperluas pada waktu kompilasi menjadi kode yang lebih kompleks mengikuti suatu pola. Kode yang dihasilkan menggunakan instruksi JVM yang selalu ada.
A switch
dengan String
kasing diterjemahkan ke dalam dua sakelar selama kompilasi. Yang pertama memetakan setiap string ke integer unik — posisinya dalam sakelar asli. Ini dilakukan dengan terlebih dahulu menyalakan kode hash label. Kasing yang sesuai adalah if
pernyataan yang menguji kesetaraan string; jika ada tabrakan pada hash, tes ini adalah cascading if-else-if
. Saklar kedua mencerminkan bahwa dalam kode sumber asli, tetapi mengganti label case dengan posisi yang sesuai. Proses dua langkah ini membuatnya mudah untuk mempertahankan kontrol aliran sakelar asli.
Beralih di JVM
Untuk kedalaman teknis lebih lanjut switch
, Anda dapat merujuk ke Spesifikasi JVM, di mana kompilasi pernyataan switch dijelaskan. Singkatnya, ada dua instruksi JVM yang berbeda yang dapat digunakan untuk sakelar, tergantung pada tingkat konstanta yang digunakan oleh kasing. Keduanya bergantung pada penggunaan konstanta integer untuk setiap kasus untuk dieksekusi secara efisien.
Jika konstanta padat, mereka digunakan sebagai indeks (setelah mengurangi nilai terendah) ke dalam tabel petunjuk instruksi — tableswitch
instruksi.
Jika konstanta jarang, pencarian biner untuk kasus yang benar dilakukan — lookupswitch
instruksi.
Dalam de-sugaring sebuah switch
pada String
benda-benda, baik instruksi yang mungkin untuk digunakan. The lookupswitch
cocok untuk switch pertama pada kode hash untuk menemukan posisi asli dari kasus ini. Ordinal yang dihasilkan adalah cocok alami untuk a tableswitch
.
Kedua instruksi membutuhkan konstanta integer yang ditugaskan untuk setiap kasus untuk diurutkan pada waktu kompilasi. Saat runtime, sementara O(1)
kinerja tableswitch
umumnya tampak lebih baik daripada O(log(n))
kinerja lookupswitch
, itu memerlukan beberapa analisis untuk menentukan apakah tabel cukup padat untuk membenarkan tradeoff ruang-waktu. Bill Venners menulis sebuah artikel hebat yang membahas hal ini secara lebih rinci, bersama dengan pandangan di bawah kap pada instruksi kontrol aliran Java lainnya.
Sebelum JDK 7
Sebelum ke JDK 7, enum
bisa mendekati String
switch berbasis. Ini menggunakan metode statisvalueOf
yang dihasilkan oleh kompiler pada setiap enum
jenis. Sebagai contoh:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}