Type pattern pada chapter sebelumnya mengikat nilai sebagai satu variabel bertipe record, tetapi komponennya masih harus dibuka satu per satu lewat accessor: g.awal().x(), g.akhir().x(), dan seterusnya. Untuk struktur bersarang — garis yang tersusun dari dua titik, segitiga dari tiga titik — rantai accessor itu cepat menumpuk dan menyembunyikan bentuk data yang sebenarnya. Record pattern, difinalkan di Java 21 melalui JEP 440, memungkinkan label pola membedah record langsung: case Garis(Titik awal, Titik akhir) menyatakan “nilai adalah Garis yang komponennya masing-masing adalah Titik” dalam satu ekspresi deklaratif. Bab ini membedah mekanisme deconstruction itu, pola bersarang, dan kombinasi dengan var serta _.

Cara Kerja Deconstruction #

Compiler menerjemahkan record pattern menjadi rangkaian pemeriksaan yang setara dengan kode manual: uji tipe nilai terhadap Garis, panggil accessor g.awal(), uji hasilnya terhadap Titik, lalu ikat komponen berikutnya. Bedanya, compiler menjaga tipe tiap komponen tetap terpelihara dan menolak pola yang menyebut komponen tidak lengkap atau tidak cocok tipe — salah ketik nama komponen tidak mungkin lolos. Karena hanya record yang punya signature komponen yang diketahui compiler, deconstruction hanya berlaku untuk record; class biasa tetap memakai type pattern.

Membedah Bentuk Geometri #

Contoh teruji berikut memakai pola bersarang pada switch dan instanceof sekaligus:

java BedahRecord.java
public class BedahRecord {

    record Titik(int x, int y) { }
    record Garis(Titik awal, Titik akhir) { }
    record Segitiga(Titik a, Titik b, Titik c) { }

    static void deskripsi(Object bentuk) {
        String teks = switch (bentuk) {
            // Record pattern bersarang: komponen dibedah sampai level Titik.
            case Garis(Titik awal, Titik akhir) ->
                    "garis dari " + awal + " ke " + akhir;
            case Segitiga(Titik(var ax, var ay), Titik b, Titik c) ->
                    "segitiga puncak (" + ax + "," + ay + "), kaki " + b + " dan " + c;
            default -> "bentuk lain";
        };
        System.out.println(teks);
    }

    static int panjangProyeksiX(Garis g) {
        // Record pattern pada instanceof: komponen terbuka tanpa accessor.
        if (g instanceof Garis(Titik(var x1, var y1), Titik(var x2, var y2))) {
            return Math.abs(x2 - x1);
        }
        return 0;
    }

    public static void main(String[] args) {
        deskripsi(new Garis(new Titik(1, 2), new Titik(8, 6)));
        deskripsi(new Segitiga(new Titik(0, 6), new Titik(0, 0), new Titik(4, 0)));
        deskripsi("cukup");

        Garis g = new Garis(new Titik(3, 5), new Titik(9, 5));
        System.out.println("proyeksi-X: " + panjangProyeksiX(g));
    }
}

Output yang Dihasilkan:

text
garis dari Titik[x=1, y=2] ke Titik[x=8, y=6]
segitiga puncak (0,6), kaki Titik[x=0, y=0] dan Titik[x=4, y=0]
bentuk lain
proyeksi-X: 6

Bedah baris-per-baris untuk bagian pentingnya:

  1. Baris case Garis(Titik awal, Titik akhir) ->: pola record bersarang — nilai harus Garis, komponen pertamanya diikat sebagai Titik awal, komponen keduanya sebagai Titik akhir; dua nama itu langsung terpakai di sisi kanan panah.
  2. Baris case Segitiga(Titik(var ax, var ay), Titik b, Titik c) ->: kedalaman bebas — komponen pertama dibedah lagi menjadi koordinat ax dan ay lewat var, dua komponen lainnya diikat utuh sebagai Titik.
  3. Baris default -> "bentuk lain";: selector bertipe Object yang terbuka, sehingga default wajib; exhaustiveness tanpa default hanya berlaku pada selector sealed.
  4. Method panjangProyeksiX: record pattern juga sah pada instanceof — koordinat keempat titik terbuka dalam satu baris kondisi tanpa satu pun panggilan accessor eksplisit.

var dan _ di Dalam Pola #

Komponen boleh ditulis var bila tipenya ingin disimpulkan dari signature record — ringkas saat tipe komponen panjang atau generik. Sebaliknya, komponen yang memang tidak dipakai boleh ditulis _ (unnamed pattern, difinalkan di Java 22 lewat JEP 456): pola Segitiga(Titik(var ax, var ay), Titik _, Titik _) menyatakan bahwa hanya puncak yang berarti. Kombinasi lengkap pola bersarang, var, dan _ menjadikan label switch semacam spesifikasi bentuk data: barisnya berbunyi “cari nilai yang berbentuk begini”, bukan serangkaian langkah pembongkaran.

Bentuk polaContohIkat komponen
Type patterncase Garis gSatu variabel utuh
Record patterncase Garis(Titik a, Titik b)Tiap komponen
Bersarang + varcase Garis(Titik(var x1, var y1), ...)Sampai level daun
Dengan _case Garis(_, Titik akhir)Hanya yang bernama

Dari bahasa, kita beralih ke runtime: gelombang modern berikutnya Java adalah konkurensi skala besar, dimulai dari virtual thread yang membuat “satu thread per permintaan” kembali terjangkau.

Referensi #

Berkas Sumber

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

BedahRecord.java

Unduh berkas
java
public class BedahRecord {

    record Titik(int x, int y) { }
    record Garis(Titik awal, Titik akhir) { }
    record Segitiga(Titik a, Titik b, Titik c) { }

    static void deskripsi(Object bentuk) {
        String teks = switch (bentuk) {
            // Record pattern bersarang: komponen dibedah sampai level Titik.
            case Garis(Titik awal, Titik akhir) ->
                    "garis dari " + awal + " ke " + akhir;
            case Segitiga(Titik(var ax, var ay), Titik b, Titik c) ->
                    "segitiga puncak (" + ax + "," + ay + "), kaki " + b + " dan " + c;
            default -> "bentuk lain";
        };
        System.out.println(teks);
    }

    static int panjangProyeksiX(Garis g) {
        // Record pattern pada instanceof: komponen terbuka tanpa accessor.
        if (g instanceof Garis(Titik(var x1, var y1), Titik(var x2, var y2))) {
            return Math.abs(x2 - x1);
        }
        return 0;
    }

    public static void main(String[] args) {
        deskripsi(new Garis(new Titik(1, 2), new Titik(8, 6)));
        deskripsi(new Segitiga(new Titik(0, 6), new Titik(0, 0), new Titik(4, 0)));
        deskripsi("cukup");

        Garis g = new Garis(new Titik(3, 5), new Titik(9, 5));
        System.out.println("proyeksi-X: " + panjangProyeksiX(g));
    }
}