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:
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:
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: 6Bedah baris-per-baris untuk bagian pentingnya:
- Baris
case Garis(Titik awal, Titik akhir) ->: pola record bersarang — nilai harusGaris, komponen pertamanya diikat sebagaiTitik awal, komponen keduanya sebagaiTitik akhir; dua nama itu langsung terpakai di sisi kanan panah. - Baris
case Segitiga(Titik(var ax, var ay), Titik b, Titik c) ->: kedalaman bebas — komponen pertama dibedah lagi menjadi koordinataxdanaylewatvar, dua komponen lainnya diikat utuh sebagaiTitik. - Baris
default -> "bentuk lain";: selector bertipeObjectyang terbuka, sehinggadefaultwajib; exhaustiveness tanpadefaulthanya berlaku pada selectorsealed. - Method
panjangProyeksiX: record pattern juga sah padainstanceof— 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 pola | Contoh | Ikat komponen |
|---|---|---|
| Type pattern | case Garis g | Satu variabel utuh |
| Record pattern | case Garis(Titik a, Titik b) | Tiap komponen |
Bersarang + var | case 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 berkaspublic 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));
}
}