Statement switch warisan Java 1.0 punya dua kelemahan yang sudah terasa puluhan tahun: lupa break membuat eksekusi jatuh ke case berikutnya (fall-through), dan switch tidak menghasilkan nilai sehingga hasilnya harus ditampung lewat variabel sementara yang diisi case demi case. Switch expression, difinalkan di Java 14 melalui JEP 361, memperbaiki keduanya sekaligus: bentuk baru ber-arrow label tidak pernah jatuh ke case lain, dan seluruh switch menjadi ekspresi yang mengembalikan nilai. Chapter ini membahas bentuk baru tersebut, kata kunci yield, serta jaminan kelengkapan yang diperiksa compiler.
Arrow Label Tanpa Fall-Through #
Bentuk modern memakai tanda panah -> alih-alih titik dua. Eksekusi case tidak pernah meneruskan ke case berikutnya, sehingga break menghilang sama sekali. Sisi kanan panah bisa berupa nilai tunggal, ekspresi, blok kode, atau throw:
int diskon = switch (hari) {
case SABTU, MINGGU -> 30;
case JUMAT -> member ? 20 : 15;
case SENIN -> {
int dasar = 10;
yield member ? dasar + 5 : dasar;
}
default -> 5;
};Kata kunci yield hanya dipakai ketika sisi kanan berupa blok kurung kurawal: blok menjalankan pernyataan apa pun, lalu yield menyerahkan nilai hasilnya ke ekspresi switch. Untuk gaya lama berlabel titik dua yang masih sah dipakai, yield menggantikan peran variabel penampung.
Menghitung Diskon dengan Switch Expression #
Contoh teruji berikut menghitung diskon toko per hari dan status member, lalu mencetak seluruh kombinasi dari sebuah enum:
public class DiskonGayaBaru {
enum Hari { SENIN, SELASA, RABU, KAMIS, JUMAT, SABTU, MINGGU }
static int diskon(Hari hari, boolean member) {
return switch (hari) {
case SABTU, MINGGU -> 30; // label multi-konstanta
case JUMAT -> member ? 20 : 15; // hasil ekspresi langsung
case SENIN -> { // blok perlu kata kunci yield
int dasar = 10;
yield member ? dasar + 5 : dasar;
}
default -> 5;
};
}
public static void main(String[] args) {
System.out.println("hari member non-member");
for (var hari : Hari.values()) {
System.out.printf("%-8s %4d%% %8d%%%n",
hari, diskon(hari, true), diskon(hari, false));
}
}
}Output yang Dihasilkan:
hari member non-member
SENIN 15% 10%
SELASA 5% 5%
RABU 5% 5%
KAMIS 5% 5%
JUMAT 20% 15%
SABTU 30% 30%
MINGGU 30% 30%Bedah baris-per-baris untuk bagian pentingnya:
- Baris
static int diskon(Hari hari, boolean member): method mengembalikan hasilswitchlangsung lewatreturn switch (...)— tidak ada variabel sementara. - Baris
case SABTU, MINGGU -> 30;: satu label menampung beberapa konstanta yang dipisah koma; tanpabreak, tanpa risiko fall-through. - Baris
case JUMAT -> member ? 20 : 15;: sisi kanan boleh berupa ekspresi kondisional yang dievaluasi saat case terpilih. - Baris
case SENIN -> { ... yield ...; }: blok mendeklarasikan variabel lokaldasarlalu menyerahkan hasil lewatyield— pola untuk logika case yang lebih dari satu baris. - Baris
for (var hari : Hari.values()): perulangan mencetak tujuh hari dengan format kolom rata sehingga tabel terbaca.
Kelengkapan yang Diperiksa Compiler #
Switch expression wajib menghasilkan nilai untuk semua input yang mungkin. Ketika selektornya bertipe enum tanpa default, compiler menghitung setiap konstanta dan menolak bila ada yang terlewat — error paling umum ketika menambah konstanta enum baru lupa memperbarui switch. Contoh gagal berikut membuktikannya:
public class SwitchTakLengkap {
enum Warna { MERAH, HIJAU, BIRU }
public static void main(String[] args) {
Warna w = Warna.BIRU;
// Switch expression wajib mencakup seluruh nilai enum (tanpa default).
int kode = switch (w) {
case MERAH -> 1;
case HIJAU -> 2;
};
System.out.println(kode);
}
}Compiler javac menolak berkas tersebut dengan pesan the switch expression does not cover all possible input values: konstanta BIRU tidak memiliki label. Perbaikannya sederhana — tambahkan case BIRU, atau tulis default. Keuntungan nyatanya: kesalahan tertangkap saat kompilasi, bukan saat program berjalan dengan nilai tak terduga.
Statement Lama dan Expression Baru #
| Aspek | switch statement (lama) | switch expression (Java 14+) |
|---|---|---|
| Menghasilkan nilai | Tidak | Ya, lewat sisi kanan -> atau yield |
| Fall-through ke case berikut | Ya bila lupa break | Tidak ada pada arrow label |
| Pemeriksaan kelengkapan | Tidak ada | Wajib untuk expression |
| Multi-konstanta per label | case A: case B: | case A, B -> |
Statement lama tetap sah dan berguna untuk efek samping murni; bentuk expression menjadi pilihan utama begitu sebuah keputusan harus menghasilkan nilai.
Dengan selektor bertipe enum kita mendapat kelengkapan otomatis. Batasnya, enum masih memerlukan label per konstanta dan instanceof manual ketika bekerja dengan tipe data campuran — masalah yang diselesaikan pattern matching untuk switch pada chapter Pattern Matching. Sebelum ke sana, kita selesaikan dulu literal teks yang panjang dengan text block.
Referensi #
- OpenJDK: JEP 361 — Switch Expressions
- Oracle: The Java Language Specification, Java SE 25 — switch Expressions
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
DiskonGayaBaru.java
Unduh berkaspublic class DiskonGayaBaru {
enum Hari { SENIN, SELASA, RABU, KAMIS, JUMAT, SABTU, MINGGU }
static int diskon(Hari hari, boolean member) {
return switch (hari) {
case SABTU, MINGGU -> 30; // label multi-konstanta
case JUMAT -> member ? 20 : 15; // hasil ekspresi langsung
case SENIN -> { // blok perlu kata kunci yield
int dasar = 10;
yield member ? dasar + 5 : dasar;
}
default -> 5;
};
}
public static void main(String[] args) {
System.out.println("hari member non-member");
for (var hari : Hari.values()) {
System.out.printf("%-8s %4d%% %8d%%%n",
hari, diskon(hari, true), diskon(hari, false));
}
}
}
SwitchTakLengkap.java
Unduh berkaspublic class SwitchTakLengkap {
enum Warna { MERAH, HIJAU, BIRU }
public static void main(String[] args) {
Warna w = Warna.BIRU;
// Switch expression wajib mencakup seluruh nilai enum (tanpa default).
int kode = switch (w) {
case MERAH -> 1;
case HIJAU -> 2;
};
System.out.println(kode);
}
}