Tampilan
Kenapa penting
Kode backend yang sehat terdiri dari banyak bagian kecil yang masing-masing punya satu tugas: memvalidasi input, menghitung harga, menentukan ongkos kirim. Di Java, bagian kecil itu adalah method. Method membuat logika bisa dipakai ulang, diuji satu per satu, dan dibaca seperti kalimat — shippingCost(weight, zone) jauh lebih jelas daripada dua puluh baris perhitungan di tengah main. Semua yang nanti kamu tulis di Spring Boot (controller, service, repository) pada dasarnya adalah kumpulan method.
Konsep inti
Anatomi method
java
public class Invoice {
static long subtotal(long unitPrice, int quantity) {
return unitPrice * quantity;
}
static void printLine(String item, long amount) {
System.out.println(item + ": Rp" + amount);
}
public static void main(String[] args) {
long coffee = subtotal(25_000, 2);
printLine("Kopi", coffee);
printLine("Roti", subtotal(18_000, 3));
}
}Output:
text
Kopi: Rp50000
Roti: Rp54000Bagian-bagian deklarasi static long subtotal(long unitPrice, int quantity):
| Bagian | Arti |
|---|---|
static | method milik class, dipanggil tanpa membuat object (object di M02) |
long | tipe nilai kembalian; void bila method tidak mengembalikan apa-apa |
subtotal | nama method — kata kerja/frasa dalam camelCase |
(long unitPrice, int quantity) | parameter: variabel lokal yang diisi oleh pemanggil |
{ ... } | badan method; return mengirim nilai balik ke pemanggil |
Nilai yang dikirim saat memanggil — 25_000 dan 2 — disebut argumen. Jumlah, urutan, dan tipenya harus cocok dengan parameter. Hasil method bisa disimpan ke variabel (long coffee = ...) atau langsung dipakai sebagai argumen method lain, seperti printLine("Roti", subtotal(18_000, 3)).
return dan method void
Method bertipe kembalian wajib mengembalikan nilai di setiap jalur eksekusi; jika ada jalur yang terlewat, compiler menolak dengan pesan missing return statement. return juga langsung mengakhiri method, sehingga kamu bisa memakai pola early return untuk menghindari if bersarang:
java
public class EarlyReturn {
static String passwordStrength(int length) {
if (length < 8) {
return "lemah";
}
if (length < 12) {
return "cukup";
}
return "kuat";
}
public static void main(String[] args) {
System.out.println(passwordStrength(6));
System.out.println(passwordStrength(10));
System.out.println(passwordStrength(16));
}
}Output: lemah, cukup, kuat (satu per baris). Method void seperti printLine melakukan aksi (mencetak, menyimpan) tanpa menghasilkan nilai; di dalamnya return; tanpa nilai boleh dipakai untuk keluar lebih awal.
Overloading
Beberapa method boleh memakai nama yang sama asalkan daftar parameternya berbeda — jumlah, tipe, atau urutan tipenya. Ini disebut overloading. Tipe kembalian saja tidak cukup untuk membedakan: int parse(String s) dan long parse(String s) di class yang sama membuat compiler menolak dengan pesan already defined.
java
public class Overloading {
static String formatDuration(int seconds) {
return formatDuration(seconds / 60, seconds % 60);
}
static String formatDuration(int minutes, int seconds) {
return minutes + " menit " + seconds + " detik";
}
static String formatDuration(double hours) {
return hours + " jam";
}
public static void main(String[] args) {
System.out.println(formatDuration(135));
System.out.println(formatDuration(3, 5));
System.out.println(formatDuration(1.5));
}
}Output:
text
2 menit 15 detik
3 menit 5 detik
1.5 jamCompiler memilih versi yang paling cocok dengan tipe argumen saat kompilasi. Perhatikan juga bahwa formatDuration(int) memanggil formatDuration(int, int) — overload yang sederhana sebaiknya meneruskan ke versi yang lebih lengkap agar logikanya tidak ditulis dua kali.
Pass-by-value
Java selalu pass-by-value: saat method dipanggil, nilai argumen disalin ke parameter. Mengubah parameter di dalam method tidak mengubah variabel milik pemanggil.
java
public class PassByValue {
static void addBonus(int points) {
points = points + 100;
System.out.println("Di dalam method: " + points);
}
static void shout(String text) {
text = text + "!";
}
public static void main(String[] args) {
int points = 50;
addBonus(points);
System.out.println("Setelah dipanggil: " + points);
String name = "Budi";
shout(name);
System.out.println(name);
}
}Output:
text
Di dalam method: 150
Setelah dipanggil: 50
BudiUntuk tipe referensi seperti String, yang disalin adalah referensinya. text = text + "!" membuat String baru dan hanya mengarahkan salinan referensi text ke sana — name di main tetap menunjuk "Budi". (String juga immutable: isinya memang tidak bisa diubah.) Akibat pass-by-value pada object yang bisa diubah akan kamu lihat di M02. Pelajarannya: kalau method menghitung sesuatu, kembalikan hasilnya dengan return, jangan berharap parameter berubah.
Method kecil dan penamaan
- Satu method, satu tugas. Kalau kamu butuh kata "dan" untuk menjelaskannya, mungkin perlu dipecah.
- Nama berupa kata kerja dalam camelCase:
calculateTotal,sendEmail. Method yang mengembalikanbooleanbiasanya diawaliis/has/can:isValidWeight,hasStock. - Parameter sedikit (idealnya ≤ 3–4) dengan nama yang menjelaskan satuan bila perlu:
weightGrams,timeoutMillis.
Sekilas rekursi
Method boleh memanggil dirinya sendiri — disebut rekursi. Syaratnya ada kasus dasar yang menghentikan pemanggilan:
java
public class Recursion {
static long factorial(int n) {
if (n <= 1) {
return 1; // kasus dasar: menghentikan rekursi
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
System.out.println(factorial(5));
}
}Output: 120. Di kode backend sehari-hari rekursi jarang dipakai (loop biasanya lebih sederhana), tetapi kamu akan menemuinya saat mengolah struktur bertingkat seperti kategori produk atau komentar berbalas.
Contoh di dunia backend
Layanan pengiriman menghitung ongkos kirim. Alih-alih satu blok besar, logikanya dipecah menjadi method kecil yang masing-masing mudah diuji:
java
public class ShippingService {
static boolean isValidWeight(int weightGrams) {
return weightGrams > 0 && weightGrams <= 30_000;
}
static int ratePerKg(String zone) {
return switch (zone) {
case "JAWA" -> 10_000;
case "SUMATERA", "BALI" -> 18_000;
default -> 30_000;
};
}
static int billableKg(int weightGrams) {
// pembulatan ke atas: 1.001 gram ditagih 2 kg
return (weightGrams + 999) / 1000;
}
static long shippingCost(int weightGrams, String zone) {
if (!isValidWeight(weightGrams)) {
return -1; // penanda tidak valid; cara yang lebih baik (exception) dibahas di M03
}
return (long) billableKg(weightGrams) * ratePerKg(zone);
}
public static void main(String[] args) {
System.out.println(shippingCost(1_500, "JAWA"));
System.out.println(shippingCost(2_000, "BALI"));
System.out.println(shippingCost(45_000, "JAWA"));
}
}Output: 20000, 36000, dan -1. Method shippingCost terbaca seperti aturan bisnisnya: validasi berat, hitung kg yang ditagih, kalikan dengan tarif zona. Di Spring Boot nanti, method-method seperti ini akan menjadi method instance di sebuah class service — konsep parameter, return, dan overloading-nya sama persis.
Pertanyaan interview
1. Apakah Java pass-by-value atau pass-by-reference?
Selalu pass-by-value. Untuk primitif yang disalin adalah nilainya; untuk object yang disalin adalah referensinya. Karena itu method bisa mengubah isi object yang mutable (misalnya array), tetapi tidak bisa membuat variabel milik pemanggil menunjuk object lain.
2. Apa beda overloading dan overriding?
Overloading: beberapa method bernama sama dengan daftar parameter berbeda, dipilih compiler saat kompilasi. Overriding: subclass mengganti implementasi method milik induknya dengan signature yang sama, dipilih saat program berjalan — dibahas di modul OOP (M02).
3. Seperti apa method yang baik menurutmu?
Punya satu tanggung jawab, nama kata kerja yang jelas, parameter sedikit, dan tanpa efek samping tersembunyi — hasilnya dikembalikan lewat return alih-alih mengubah input. Method seperti ini mudah dibaca, dipakai ulang, dan diuji dengan unit test.
Jebakan umum
- Mengira parameter yang diubah ikut mengubah variabel pemanggil. Java pass-by-value; kembalikan hasilnya dengan
returndan simpan di pemanggil:price = applyDiscount(price, 10);. - Membedakan overload hanya dari tipe kembalian → error
already defined. Bedakan lewat daftar parameter. - Overload yang membingungkan —
total(long, int)dantotal(int, long)sekaligus membuat pemanggilan sulit ditebak. Buat overload yang jelas bedanya, atau pakai nama berbeda. - Lupa
returndi salah satu cabang →missing return statement. Pastikan setiap jalurif/elsepunyareturn. - Method raksasa yang memvalidasi, menghitung, dan mencetak sekaligus — sulit diuji dan dipakai ulang. Pecah menjadi method kecil.
Ringkasan
- Method dideklarasikan dengan tipe kembalian, nama, dan daftar parameter; argumen saat memanggil harus cocok.
- Method non-
voidwajibreturndi setiap jalur;returnjuga mengakhiri method (pola early return). - Overloading = nama sama, daftar parameter berbeda; tipe kembalian tidak ikut membedakan.
- Java selalu pass-by-value: parameter berisi salinan nilai (atau salinan referensi).
- Method kecil dengan nama kata kerja yang jelas membuat logika backend mudah dibaca, dipakai ulang, dan diuji.