Tidak sedikit deklarasi di Java ditulis semata-mata karena tata bahasa menuntut adanya nama — padahal variabelnya tidak pernah dipakai. Loop yang hanya menghitung iterasi tetap menamai elemennya; catch yang hanya menandai kegagalan tetap mengikat variabel exception; try-with-resources tetap memberi nama sumber daya yang memang hanya perlu ditutup. Nama-nama semacam itu adalah kebisingan: pembaca mencari artinya, linter menandainya tidak terpakai. Unnamed variables, difinalkan di Java 22 melalui JEP 456, mengizinkan tanda _ menyatakan “variabel ini sengaja diabaikan” pada seluruh konteks itu — sekaligus menuntaskan sejarah panjang _ yang sejak Java 9 sudah tidak boleh dipakai sebagai nama. Chapter ini mempraktikkan seluruh konteksnya dengan satu program teruji.

Dari Nama Tak Terpakai Menjadi Penanda Niat #

Sebelum Java 22, _ berada dalam keadaan canggung: dilarang sebagai nama (int _ = 5; masih sah dideklarasikan di Java 8, lalu ditolak sejak Java 9), tetapi belum diberi peran baru. JEP 456 memberi peran itu: _ menjadi variabel tanpa nama yang boleh dideklarasikan berulang dalam scope berbeda dan tidak boleh dibaca — kompiler menolak rujukan apa pun dengan pesan underscore not allowed here, yang diverifikasi langsung pada JDK 25. Karena tidak bisa dibaca, variabel _ juga tidak menimbulkan peringatan “tidak terpakai”: diabaikan justru maknanya. Pada pattern, _ bekerja serupa sebagai pola yang cocok dengan apa pun tanpa mengikat apa pun.

Empat Konteks dalam Satu Program #

Contoh teruji berikut memakai _ sebagai lambda parameter, variabel lokal hasil deklarasi, variabel loop, komponen record pattern, dan parameter catch:

java SisiKiri.java
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SisiKiri {

    record Pasangan(int kunci, int nilai) { }

    static final Map<String, List<Integer>> BUKU_NILAI = new LinkedHashMap<>();

    static void catat(String siswa, Integer nilai) {
        // Lambda: parameter siswa tidak dipakai di badan lambda.
        BUKU_NILAI.computeIfAbsent(siswa, _ -> new ArrayList<>()).add(nilai);
    }

    static int catatSemua() {
        catat("Budi", 80);
        catat("Sita", 92);
        catat("Budi", 75);
        return 0; // nilai kembalian sengaja tidak dipedulikan
    }

    public static void main(String[] args) {
        // 1) Deklarasi: efek samping dipakai, hasilnya diabaikan.
        var _ = catatSemua();

        // 2) Loop enhanced: hanya jumlah iterasi dibutuhkan.
        int totalSiswa = 0;
        for (var _ : BUKU_NILAI.keySet()) {
            totalSiswa++;
        }

        // 3) Record pattern: komponen nilai sengaja tidak diikat.
        Object p = new Pasangan(7, 99);
        if (p instanceof Pasangan(int kunci, int _)) {
            System.out.println("kunci          : " + kunci);
        }

        // 4) catch tanpa variabel exception.
        try {
            Integer.parseInt("bukan angka");
        } catch (NumberFormatException _) {
            System.out.println("format angka   : ditolak");
        }

        System.out.println("siswa tercatat : " + totalSiswa);
        System.out.println("buku nilai     : " + BUKU_NILAI);
    }
}

Output yang Dihasilkan:

text
kunci          : 7
format angka   : ditolak
siswa tercatat : 2
buku nilai     : {Budi=[80, 75], Sita=[92]}

Bedah baris-per-baris untuk bagian pentingnya:

  1. Baris BUKU_NILAI.computeIfAbsent(siswa, _ -> new ArrayList<>()): lambda penerima kunci tidak memakai parameternya; _ menggantikan nama seperti k atau siswaLagi yang hanya menipu pembaca.
  2. Baris var _ = catatSemua();: nilai kembalian int dari catatSemua() sengaja dibuang — kita hanya ingin efek sampingnya mencatat nilai; tata bahasa tetap puas, pembaca tidak dibuat bertanya-tanya.
  3. Baris for (var _ : BUKU_NILAI.keySet()): loop hanya menghitung jumlah siswa; elemen tidak pernah dibaca, dan _ menyatakannya di tempat.
  4. Baris if (p instanceof Pasangan(int kunci, int _)): record pattern mengikat kunci saja; komponen nilai dicocokkan strukturnya lalu diabaikan.
  5. Blok catch (NumberFormatException _): handler hanya mencetak pesan tetap; objek exception tidak dirujuk, dan stack trace pun tidak diperlukan.

Konteks Lengkap dan Sejarahnya #

KonteksBentukFinal sejak
Variabel lokalvar _ = hitung();Java 22
Loop for / enhanced forfor (var _ : kumpulan)Java 22
try-with-resourcestry (var _ = buka())Java 22
catchcatch (IOException _)Java 22
Parameter lambdapeta.computeIfAbsent(k, _ -> ...)Java 22
Type pattern & record patterncase Titik _ / case Titik(var x, _)Java 22

Kebiasaan kecil ini menuntaskan peta fitur bahasa modern. Satu chapter tersisa di Section ini: bagaimana semua perubahan ini memasuki aplikasi lama tanpa menimbulkan keretakan — compatibility dan migration.

Referensi #

Berkas Sumber

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

SisiKiri.java

Unduh berkas
java
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SisiKiri {

    record Pasangan(int kunci, int nilai) { }

    static final Map<String, List<Integer>> BUKU_NILAI = new LinkedHashMap<>();

    static void catat(String siswa, Integer nilai) {
        // Lambda: parameter siswa tidak dipakai di badan lambda.
        BUKU_NILAI.computeIfAbsent(siswa, _ -> new ArrayList<>()).add(nilai);
    }

    static int catatSemua() {
        catat("Budi", 80);
        catat("Sita", 92);
        catat("Budi", 75);
        return 0; // nilai kembalian sengaja tidak dipedulikan
    }

    public static void main(String[] args) {
        // 1) Deklarasi: efek samping dipakai, hasilnya diabaikan.
        var _ = catatSemua();

        // 2) Loop enhanced: hanya jumlah iterasi dibutuhkan.
        int totalSiswa = 0;
        for (var _ : BUKU_NILAI.keySet()) {
            totalSiswa++;
        }

        // 3) Record pattern: komponen nilai sengaja tidak diikat.
        Object p = new Pasangan(7, 99);
        if (p instanceof Pasangan(int kunci, int _)) {
            System.out.println("kunci          : " + kunci);
        }

        // 4) catch tanpa variabel exception.
        try {
            Integer.parseInt("bukan angka");
        } catch (NumberFormatException _) {
            System.out.println("format angka   : ditolak");
        }

        System.out.println("siswa tercatat : " + totalSiswa);
        System.out.println("buku nilai     : " + BUKU_NILAI);
    }
}