Pola “ciptakan object lalu isi field satu per satu” pada Chapter sebelumnya punya dua kelemahan nyata: boros baris kode, dan yang lebih penting, mengizinkan object setengah jadi beredar di program. Object Buku tanpa judul dan dengan stok masih bernilai 0 adalah undangan galat — suatu saat pasti ada kode yang membacanya. Java menutup celah ini dengan constructor: blok kode khusus yang dijalankan JVM secara otomatis tepat setelah new mengalokasikan memori object, sebelum referensi object diserahkan ke pemanggil. Pada Chapter ini kita pelajari aturan penulisan constructor, perbedaannya dari method biasa, serta dua bentuknya: tanpa argumen dan berparameter.

Peran Constructor Saat new Dijalankan #

Ekspresi new Buku(...) sebenarnya menjalankan dua tahap. Tahap pertama, JVM mengalokasikan memori untuk object Buku dan mengisi seluruh field dengan nilai bawaan. Tahap kedua, JVM menjalankan constructor yang cocok dengan argumen yang kita berikan, dan constructor inilah kesempatan pertama — biasanya satu-satunya yang kita butuhkan — untuk mengisi field dengan nilai bermakna. Referensi object hanya diserahkan ke variabel setelah kedua tahap selesai, sehingga object yang kita terima selalu sudah melewati proses inisialisasi.

Mari kita lengkapi class Buku dengan constructor berparameter. Supaya eksekusinya terlihat, constructor ini mencetak satu baris teks setiap kali berjalan:

java Buku.java
class Buku {
    String judul;
    String penulis;
    int tahunTerbit;
    int stok;

    Buku(String judul, String penulis, int tahunTerbit, int stok) {
        System.out.println("Constructor Buku dijalankan untuk: " + judul);
        this.judul = judul;
        this.penulis = penulis;
        this.tahunTerbit = tahunTerbit;
        this.stok = stok;
    }

    void tampilkanInfo() {
        System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis
                + " | stok: " + stok);
    }
}

Program pemanggilnya kini ringkas: seluruh data diserahkan pada saat new, tanpa satu pun assignment field manual di main:

public class AplikasiKonstruktor {
    public static void main(String[] args) {
        Buku bukuA = new Buku("Laskar Pelangi", "Andrea Hirata", 2005, 3);
        Buku bukuB = new Buku("Bumi Manusia", "Pramoedya Ananta Toer", 1980, 1);

        System.out.println("--- daftar buku ---");
        bukuA.tampilkanInfo();
        bukuB.tampilkanInfo();
    }
}

Output yang Dihasilkan:

text
Constructor Buku dijalankan untuk: Laskar Pelangi
Constructor Buku dijalankan untuk: Bumi Manusia
--- daftar buku ---
Laskar Pelangi (2005) oleh Andrea Hirata | stok: 3
Bumi Manusia (1980) oleh Pramoedya Ananta Toer | stok: 1

Urutan baris pada output adalah bukti langsung waktu eksekusi constructor: dua baris “Constructor Buku dijalankan” tercetak lebih dulu — masing-masing muncul tepat saat new dievaluasi — sebelum garis pemisah dan daftar buku yang dicetak main. Mari kita bedah baris-per-baris:

  1. Baris 4-5 pada Buku.java (Buku(String judul, ...)): inilah deklarasi constructor. Namanya sama persis dengan nama class, daftar parameternya ditulis dalam kurung, dan tidak ada tipe kembalian sama sekali — tiga ciri yang membedakannya dari method.
  2. Baris 6 (System.out.println("Constructor Buku dijalankan untuk: " + judul);): judul tanpa awalan apa pun merujuk ke parameter, karena parameter menutupi (shadowing) field yang bernama sama. Baris ini mencetak judul dari argumen pemanggil.
  3. Baris 7-10 (this.judul = judul; dst.): awalan this. memaksa sisi kiri merujuk ke field object, sehingga keempat baris menyalin nilai parameter ke field. Kata kunci this akan kita bedah tuntas pada Chapter Keyword this; untuk sekarang, cukup ingat bahwa pola this.field = parameter adalah cara baku mengisi field di constructor.
  4. Baris 4-5 pada AplikasiKonstruktor.java (new Buku(...)): setiap new menjalankan constructor satu kali penuh. Dua object lahir dalam keadaan lengkap — tidak ada satu baris pun pengisian field manual di main.

Aturan Penulisan Constructor #

Compiler javac mengenali constructor lewat dua tanda wajib: nama yang identik dengan nama class, dan tidak adanya tipe kembalian — bukan void, bukan apa pun. Pelanggaran aturan kedua tidak menghasilkan error; yang terjadi justru lebih licik: blok tersebut diperlakukan sebagai method biasa. Misalnya, void Buku(...) adalah method bernama Buku, dan pemanggilan new Buku() akan gagal karena compiler tidak menemukan constructor apa pun. Galat seperti ini biasanya baru terdeteksi saat kompilasi program pemanggil, bukan saat class ditulis.

Constructor boleh berisi pernyataan biasa — percabangan, pengisian field, bahkan pemanggilan method — dan lazim juga dipakai untuk validasi sederhana. Konvensi penamaan parameter constructor yang meniru nama field (judul, penulis) adalah gaya yang dominan di ekosistem Java karena terbaca natural di sisi pemanggil, ditukar dengan kewajiban memakai this. di dalam badan constructor.

Constructor Tanpa Argumen dan Constructor Bawaan #

Bentuk kedua yang sering kita butuhkan adalah constructor tanpa argumen (no-arg constructor): cocok untuk object yang datanya memang baku, atau yang akan diisi belakangan lewat method. Program berikut menunjukkan constructor tanpa argumen yang memasang nilai tetap:

public class KonstruktorTanpaArgumen {
    public static void main(String[] args) {
        BukuPanduan panduan = new BukuPanduan();
        panduan.tampilkanInfo();
    }
}

class BukuPanduan {
    String judul;
    String penulis;
    int tahunTerbit;

    BukuPanduan() {
        System.out.println("Constructor BukuPanduan() dijalankan");
        judul = "Panduan Anggota Perpustakaan";
        penulis = "Siti Rahmawati";
        tahunTerbit = 2026;
    }

    void tampilkanInfo() {
        System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis);
    }
}

Output yang Dihasilkan:

text
Constructor BukuPanduan() dijalankan
Panduan Anggota Perpustakaan (2026) oleh Siti Rahmawati

Bagian terpenting dari contoh ini justru yang tidak terlihat di kode. Selama kita belum menulis satu pun constructor, compiler diam-diam menambahkan default constructor tanpa argumen dan tanpa isi — itulah sebabnya new Buku() pada Chapter sebelumnya selalu berhasil meski class Buku tidak punya constructor. Perilaku ini berubah drastis begitu kita menulis constructor pertama kita: compiler berhenti menyisipkan default constructor. Akibatnya, setelah class Buku kita dilengkapi constructor berparameter, pemanggilan new Buku() yang tadinya sah kini ditolak compiler dengan pesan verbatim berikut:

text
error: constructor Buku in class Buku cannot be applied to given types;
        Buku buku = new Buku();
                    ^
  required: String,String,int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length

Constructor mengubah ritual penciptaan object dari tiga baris penugasan menjadi satu ekspresi new yang berdata. Namun aplikasi nyata jarang puas dengan satu bentuk penciptaan: kadang data lengkap tersedia, kadang hanya sebagian. Java mengizinkan satu class memiliki beberapa constructor dengan daftar parameter berbeda — dan bahkan membiarkan constructor saling mendelegasikan pekerjaan lewat this(...). Keduanya adalah pokok bahasan Chapter berikutnya.

Referensi #

Berkas Sumber

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

AplikasiKonstruktor.java

Unduh berkas
java
public class AplikasiKonstruktor {
    public static void main(String[] args) {
        Buku bukuA = new Buku("Laskar Pelangi", "Andrea Hirata", 2005, 3);
        Buku bukuB = new Buku("Bumi Manusia", "Pramoedya Ananta Toer", 1980, 1);

        System.out.println("--- daftar buku ---");
        bukuA.tampilkanInfo();
        bukuB.tampilkanInfo();
    }
}

Buku.java

Unduh berkas
java
class Buku {
    String judul;
    String penulis;
    int tahunTerbit;
    int stok;

    Buku(String judul, String penulis, int tahunTerbit, int stok) {
        System.out.println("Constructor Buku dijalankan untuk: " + judul);
        this.judul = judul;
        this.penulis = penulis;
        this.tahunTerbit = tahunTerbit;
        this.stok = stok;
    }

    void tampilkanInfo() {
        System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis
                + " | stok: " + stok);
    }
}

KonstruktorTanpaArgumen.java

Unduh berkas
java
public class KonstruktorTanpaArgumen {
    public static void main(String[] args) {
        BukuPanduan panduan = new BukuPanduan();
        panduan.tampilkanInfo();
    }
}

class BukuPanduan {
    String judul;
    String penulis;
    int tahunTerbit;

    BukuPanduan() {
        System.out.println("Constructor BukuPanduan() dijalankan");
        judul = "Panduan Anggota Perpustakaan";
        penulis = "Siti Rahmawati";
        tahunTerbit = 2026;
    }

    void tampilkanInfo() {
        System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis);
    }
}