Program yang seluruh logikanya ditumpuk di dalam main akan memanjang dengan cepat: blok kode yang sama disalin-tempel di beberapa tempat, satu perbaikan harus dilakukan berulang kali, dan membaca alur program menjadi pekerjaan yang melelahkan. Java menyediakan method sebagai unit kerja kecil yang bernama — sekali didefinisikan, method dapat dipanggil dari mana pun sebanyak apa pun. Pada Chapter ini kita bedah anatomi deklarasi method, menulis method pertama, lalu mengamati bagaimana JVM mengatur pemanggilan method melalui call stack dan stack frame.

Anatomi Deklarasi Method #

Setiap method di Java hidup di dalam sebuah class — tidak ada method yang berdiri sendiri di luar class. Bentuk umum deklarasinya seperti berikut:

text Bentuk umum deklarasi method
modifier returnType namaMethod(daftarParameter) {
    // badan method: pernyataan yang dijalankan saat method dipanggil
}

Empat bagian penyusunnya perlu kita kenali satu per satu:

BagianPeranContoh
modifierMengatur akses dan kepemilikan methodpublic, private, static
returnTypeTipe nilai yang dikembalikan, atau void jika tidak adavoid, int, String
namaMethodIdentifier pemanggilanhitungTotal, tampilkanJudul
daftarParameterMasukan bertipe yang diterima methodString nama, () kosong

Modifier bersifat opsional dalam arti boleh dikombinasikan, tetapi setiap method wajib memiliki return type dan nama. Return type void menyatakan method menjalankan aksi tanpa mengembalikan nilai — hasil kerjanya berupa efek seperti mencetak ke terminal. Daftar parameter yang kosong ditulis (); method seperti ini bekerja tanpa masukan dari pemanggil.

Method Pertama Kita #

Mari kita tulis class dengan dua method: satu tanpa parameter yang mencetak judul, dan satu yang menerima nama untuk disapa:

java HaloMethod.java
public class HaloMethod {

    // Method tanpa parameter dan tanpa nilai balik (void)
    static void tampilkanJudul() {
        System.out.println("=== Laporan Penjualan ===");
    }

    // Method dengan satu parameter bernama nama
    static void sapa(String nama) {
        System.out.println("Halo, " + nama + "! Selamat belajar method.");
    }

    public static void main(String[] args) {
        tampilkanJudul();
        sapa("Budi");
        sapa("Siti");
    }
}

Output yang Dihasilkan:

text
=== Laporan Penjualan ===
Halo, Budi! Selamat belajar method.
Halo, Siti! Selamat belajar method.

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (static void tampilkanJudul() {): mendeklarasikan method tampilkanJudul dengan modifier static, return type void, dan daftar parameter kosong. Badan method dibuka dengan {.
  2. Baris 5 (System.out.println(...)): satu-satunya pernyataan dalam tampilkanJudul — mencetak judul laporan ke terminal.
  3. Baris 9 (static void sapa(String nama) {): mendeklarasikan method sapa yang menerima satu parameter bertipe String bernama nama. Di dalam badan method, nama dapat dipakai seperti variabel biasa.
  4. Baris 14-16 (tampilkanJudul(); sapa("Budi"); sapa("Siti");): tiga pemanggilan method dari main. Eksekusi melompat ke badan method yang dituju, menyelesaikan seluruh pernyataannya, lalu kembali ke baris pemanggilan.

Method sapa dipanggil dua kali dengan isi berbeda — kode sapaan ditulis sekali, dipakai berkali-kali. Inilah inti modularitas: satu tempat untuk satu tanggung jawab.

Memanggil Method dan Stack Frame #

Apa yang sebenarnya terjadi ketika satu method memanggil method lain? JVM menyimpan setiap pemanggilan aktif dalam struktur data bernama call stack. Setiap kotak di call stack disebut stack frame: satu frame dibuat setiap kali method dipanggil, menyimpan parameter, variabel lokal, dan alamat untuk kembali ke pemanggil. Saat method selesai, frame-nya dibongkar dan eksekusi berlanjut di pemanggil.

Program berikut memakai method bersarang tiga tingkat agar urutan naik-turun call stack terlihat dari jejak cetaknya:

public class AlurPanggilan {

    static void cetakGaris() {
        System.out.println("cetakGaris : ------");
    }

    static void cetakHeader() {
        System.out.println("cetakHeader: mulai");
        cetakGaris();
        System.out.println("cetakHeader: selesai");
    }

    static void cetakLaporan() {
        System.out.println("cetakLaporan: mulai");
        cetakHeader();
        System.out.println("cetakLaporan: selesai");
    }

    public static void main(String[] args) {
        System.out.println("main       : mulai");
        cetakLaporan();
        System.out.println("main       : selesai");
    }
}

Output yang Dihasilkan:

text
main       : mulai
cetakLaporan: mulai
cetakHeader: mulai
cetakGaris : ------
cetakHeader: selesai
cetakLaporan: selesai
main       : selesai

Urutan hasilnya patut kita cermati. Setiap baris mulai tercetak sebelum pemanggilan berikutnya, dan setiap baris selesai tercetak setelah pemanggilan kembali — bukti bahwa eksekusi menurun ke method terdalam lalu menaik kembali:

  1. Baris 20 (System.out.println("main : mulai")): frame main adalah satu-satunya penghuni call stack; program mencetak penanda mulai.
  2. Baris 21 (cetakLaporan();): JVM membuat frame baru untuk cetakLaporan di atas frame main, lalu eksekusi berpindah ke method tersebut.
  3. Baris 15 (cetakHeader(); di dalam cetakLaporan): frame cetakHeader ditumpuk di atas frame cetakLaporan; di dalamnya cetakGaris() menumpuk satu frame lagi — call stack sempat berisi empat frame.
  4. Baris 16 (System.out.println("cetakLaporan: selesai")): baris ini baru tercapai setelah cetakHeader dan cetakGaris selesai — frame keduanya sudah dibongkar, menyisakan frame cetakLaporan dan main.

Alur naik-turun tersebut dapat digambarkan sebagai dialog berurutan:

Pemahaman tentang call stack akan terpakai langsung pada Chapter Recursive Methods, ketika satu method memanggil dirinya sendiri dan menumpuk frame berlapis-lapis. Sebelum ke sana, kita perlu meluruskan dua istilah yang sering tertukar: parameter yang dideklarasikan method, dan argument yang dikirim pemanggil — materi Chapter Parameter dan Argument.

Referensi #

Berkas Sumber

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

AlurPanggilan.java

Unduh berkas
java
public class AlurPanggilan {

    static void cetakGaris() {
        System.out.println("cetakGaris : ------");
    }

    static void cetakHeader() {
        System.out.println("cetakHeader: mulai");
        cetakGaris();
        System.out.println("cetakHeader: selesai");
    }

    static void cetakLaporan() {
        System.out.println("cetakLaporan: mulai");
        cetakHeader();
        System.out.println("cetakLaporan: selesai");
    }

    public static void main(String[] args) {
        System.out.println("main       : mulai");
        cetakLaporan();
        System.out.println("main       : selesai");
    }
}

HaloMethod.java

Unduh berkas
java
public class HaloMethod {

    // Method tanpa parameter dan tanpa nilai balik (void)
    static void tampilkanJudul() {
        System.out.println("=== Laporan Penjualan ===");
    }

    // Method dengan satu parameter bernama nama
    static void sapa(String nama) {
        System.out.println("Halo, " + nama + "! Selamat belajar method.");
    }

    public static void main(String[] args) {
        tampilkanJudul();
        sapa("Budi");
        sapa("Siti");
    }
}