Method jumlah(int a, int b, int c) hanya menerima tepat tiga angka — bagaimana bila jumlah angka tidak diketahui saat mendesain method? Sebelum Java 5, satu-satunya jalan adalah menerima array int[] dan memaksa pemanggil membangun array itu sendiri. Java menyediakan solusi yang lebih ringkas: varargs — parameter variabel-argumen yang ditulis int... nilai dan sanggup menerima nol, satu, lima, atau seratus argument sekaligus. Pada Chapter ini kita pelajari pemakaiannya, sifat aslinya sebagai array, dua batasan keras dari compiler, dan interaksinya dengan method overloading yang bisa berakhir ambigu.

Deklarasi Varargs dan Pemanggilan 0 sampai n #

Varargs dideklarasikan dengan menulis tipe, tiga titik, lalu nama parameter — contohnya int... nilai. Di dalam badan method, parameter tersebut berperilaku persis seperti array int[]: panjangnya bisa dibaca lewat nilai.length, diiterasi dengan for-each, dan dicetak rapi dengan Arrays.toString(nilai). Di sisi pemanggil, kita cukup mendaftar angka-angka dipisah koma tanpa membangun array manual:

java JumlahNilai.java
import java.util.Arrays;

public class JumlahNilai {

    // Judul wajib; daftar nilai boleh kosong sampai sepanjang apa pun
    static void tampilkan(String judul, int... nilai) {
        System.out.println(judul + " -> " + nilai.length + " nilai: " + Arrays.toString(nilai));
    }

    static int jumlah(int... nilai) {
        int total = 0;
        for (int n : nilai) {
            total += n;
        }
        return total;
    }

    public static void main(String[] args) {
        tampilkan("kosong");
        tampilkan("tunggal", 7);
        tampilkan("rapat", 7, 8, 9, 10);

        System.out.println("jumlah kosong : " + jumlah());
        System.out.println("jumlah rapat  : " + jumlah(7, 8, 9, 10));

        // Array bertipe sama dapat dikirim langsung ke parameter varargs
        int[] data = {2, 4, 6};
        System.out.println("jumlah array  : " + jumlah(data));
    }
}

Output yang Dihasilkan:

text
kosong -> 0 nilai: []
tunggal -> 1 nilai: [7]
rapat -> 4 nilai: [7, 8, 9, 10]
jumlah kosong : 0
jumlah rapat  : 34
jumlah array  : 12

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 5 (static void tampilkan(String judul, int... nilai)): kombinasi parameter biasa dan varargs — judul wajib terisi satu nilai, sedangkan nilai menampung sisa argument sebanyak apa pun, termasuk nol seperti pemanggilan tampilkan("kosong").
  2. Baris 6 (nilai.length dan Arrays.toString(nilai)): keduanya adalah perlakuan array biasa — bukti bahwa compiler mengubah int... nilai menjadi int[] nilai pada bytecode. Varargs adalah kemudahan penulisan di sisi pemanggil, bukan tipe baru.
  3. Baris 11-16 (static int jumlah(int... nilai)): method menjumlahkan seluruh nilai dengan for-each. Pemanggilan tanpa argument (jumlah()) menghasilkan array kosong sehingga totalnya 0.
  4. Baris 28-29 (jumlah(data)): array int[] asli dapat dikirim langsung tanpa dibongkar; compiler melewatinya apa adanya ke parameter int....

Varargs Harus di Posisi Terakhir #

Aturan pertama varargs bersifat mutlak: parameter varargs wajib menjadi parameter terakhir dalam daftar. Alasannya mekanis — pemanggilan seperti tampilkan(1, 2, "Data") menjadi mustahil dibaca compiler: angka 1 dan 2 bisa milik varargs, atau 2 bisa menjadi awal parameter berikutnya. Compiler menolak menebak, jadi deklarasi seperti berikut gagal dikompilasi:

public class VarargsBukanTerakhir {

    // Parameter varargs berada di tengah, bukan di akhir daftar
    static void tampilkan(int... nilai, String judul) {
        System.out.println(judul);
    }

    public static void main(String[] args) {
        tampilkan(1, 2, "Data");
    }
}

Compiler javac menolak dengan error: varargs parameter must be the last parameter sambil menunjuk parameter nilai pada baris deklarasinya. Perbaikannya adalah membalik urutan menjadi tampilkan(String judul, int... nilai) — persis bentuk yang dipakai method tampilkan pada contoh pertama. Konsekuensi lanjutannya: satu method hanya boleh memiliki satu parameter varargs, karena dua varargs tidak mungkin sama-sama berada di posisi terakhir.

Interaksi dengan Overloading Bisa Ambigu #

Varargs bertemu overloading dapat menghasilkan jebakan pemilihan method. Kasus klasiknya: satu overload varargs murni (int...) berdampingan dengan overload parameter-wajib-plus-varargs (int, int...). Pemanggilan dengan satu argument cocok dengan keduanya:

public class VarargsAmbigu {

    static int jumlah(int... nilai) {
        return 1;
    }

    static int jumlah(int wajib, int... nilai) {
        return 2;
    }

    public static void main(String[] args) {
        System.out.println(jumlah(1));
    }
}

Keluaran compiler javac untuk berkas tersebut:

text Pesan error lengkap dari javac
VarargsAmbigu.java:12: error: reference to jumlah is ambiguous
        System.out.println(jumlah(1));
                           ^
  both method jumlah(int...) in VarargsAmbigu and method jumlah(int,int...) in VarargsAmbigu match
1 error
error: compilation failed

Kata ambiguous menegaskan kedua overload sama-sama sah untuk argument 1 dan compiler menolak memilih tanpa dasar. Kasus serupa juga terjadi antara int... dan Integer... — keduanya cocok untuk argument 1 yang dapat di-boxing. Solusinya bukan menyusun overload lebih pintar, melainkan menyederhanakan desain: cukup satu varargs, atau beri nama berbeda untuk tiap bentuk masukan.

Varargs melengkapi kotak peralatan method kita: parameter tetap, return value, overloading, hingga daftar argument fleksibel. Berikutnya kita masuk ke teknik yang memanfaatkan call stack secara langsung: method yang memanggil dirinya sendiri — rekursi — beserta syarat base case yang mencegahnya berjalan tanpa henti.

Referensi #

Berkas Sumber

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

JumlahNilai.java

Unduh berkas
java
import java.util.Arrays;

public class JumlahNilai {

    // Judul wajib; daftar nilai boleh kosong sampai sepanjang apa pun
    static void tampilkan(String judul, int... nilai) {
        System.out.println(judul + " -> " + nilai.length + " nilai: " + Arrays.toString(nilai));
    }

    static int jumlah(int... nilai) {
        int total = 0;
        for (int n : nilai) {
            total += n;
        }
        return total;
    }

    public static void main(String[] args) {
        tampilkan("kosong");
        tampilkan("tunggal", 7);
        tampilkan("rapat", 7, 8, 9, 10);

        System.out.println("jumlah kosong : " + jumlah());
        System.out.println("jumlah rapat  : " + jumlah(7, 8, 9, 10));

        // Array bertipe sama dapat dikirim langsung ke parameter varargs
        int[] data = {2, 4, 6};
        System.out.println("jumlah array  : " + jumlah(data));
    }
}

VarargsAmbigu.java

Unduh berkas
java
public class VarargsAmbigu {

    static int jumlah(int... nilai) {
        return 1;
    }

    static int jumlah(int wajib, int... nilai) {
        return 2;
    }

    public static void main(String[] args) {
        System.out.println(jumlah(1));
    }
}

VarargsBukanTerakhir.java

Unduh berkas
java
public class VarargsBukanTerakhir {

    // Parameter varargs berada di tengah, bukan di akhir daftar
    static void tampilkan(int... nilai, String judul) {
        System.out.println(judul);
    }

    public static void main(String[] args) {
        tampilkan(1, 2, "Data");
    }
}