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:

java
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:

text
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:

  1. Baris static int diskon(Hari hari, boolean member): method mengembalikan hasil switch langsung lewat return switch (...) — tidak ada variabel sementara.
  2. Baris case SABTU, MINGGU -> 30;: satu label menampung beberapa konstanta yang dipisah koma; tanpa break, tanpa risiko fall-through.
  3. Baris case JUMAT -> member ? 20 : 15;: sisi kanan boleh berupa ekspresi kondisional yang dievaluasi saat case terpilih.
  4. Baris case SENIN -> { ... yield ...; }: blok mendeklarasikan variabel lokal dasar lalu menyerahkan hasil lewat yield — pola untuk logika case yang lebih dari satu baris.
  5. 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 #

Aspekswitch statement (lama)switch expression (Java 14+)
Menghasilkan nilaiTidakYa, lewat sisi kanan -> atau yield
Fall-through ke case berikutYa bila lupa breakTidak ada pada arrow label
Pemeriksaan kelengkapanTidak adaWajib untuk expression
Multi-konstanta per labelcase 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 #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

DiskonGayaBaru.java

Unduh berkas
java
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));
        }
    }
}

SwitchTakLengkap.java

Unduh berkas
java
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);
    }
}