Sejak Chapter pertama Section ini, semua method contoh kita memakai modifier static — dan kini saatnya menjawab pertanyaan yang tertunda: apa arti sebenarnya kata itu? Modifier static menentukan siapa pemilik method: method static dimiliki oleh class itu sendiri dan hidup sejak class dimuat, sedangkan method instance (non-static) dimiliki oleh setiap objek yang dibuat dari class tersebut dan hanya bisa dipanggil melalui objek. Pemilihan pemilik yang tepat adalah keputusan desain: rumus konversi suhu tidak butuh objek, sedangkan tambahSkor() tidak berarti tanpa pemain tertentu yang menyimpan skornya. Pada Chapter ini kita bandingkan keduanya dan buktikan satu batas compiler: method static tidak boleh menyentuh member instance.
Method Milik Class #
Method static terikat pada class, bukan pada objek. Pemanggilannya cukup menulis NamaClass.method(...) — tanpa new, tanpa instansiasi. Pola ini tepat untuk method yang hasilnya sepenuhnya ditentukan parameternya, seperti kumpulan rumus konversi. Class Math pada pustaka standar adalah contoh besarnya: Math.max(...), Math.abs(...), dan kawan-kawannya semuanya static.
Berkas definisi berikut menyimpan dua rumus konversi suhu:
public class Suhu {
// Method static: milik class, dipanggil tanpa membuat objek
static double celsiusKeFahrenheit(double celsius) {
return celsius * 9.0 / 5.0 + 32.0;
}
static double fahrenheitKeCelsius(double fahrenheit) {
return (fahrenheit - 32.0) * 5.0 / 9.0;
}
}Method main yang selama ini kita tulis juga static — dan bukan kebetulan: JVM harus bisa memanggil titik masuk program sebelum objek apa pun tercipta, sehingga main wajib dimiliki class.
Method Milik Objek #
Method instance hanya hidup pada objek. Untuk memanggilnya, kita harus membuat objek dengan new lalu memanggil method lewat variabel yang menunjuk objek tersebut. Method jenis ini pun daya yang tidak dimiliki method static: membaca dan mengubah state objek — field milik objek pemanggil. Class Pemain berikut menyimpan nama dan skor sebagai state per objek:
public class Pemain {
// State milik tiap objek Pemain
String nama;
int skor;
Pemain(String nama) {
this.nama = nama;
this.skor = 0;
}
// Method instance: membaca dan menulis state objek yang memanggilnya
void tambahSkor(int poin) {
this.skor = this.skor + poin;
}
String laporan() {
return nama + " : " + skor + " poin";
}
}Program utama berikut memakai kedua class sekaligus — Suhu dipanggil lewat nama class, Pemain lewat objek:
public class ArenaPemain {
public static void main(String[] args) {
// Method static dipanggil lewat nama class, tanpa instans
System.out.println("100.0 C = " + Suhu.celsiusKeFahrenheit(100.0) + " F");
System.out.println("212.0 F = " + Suhu.fahrenheitKeCelsius(212.0) + " C");
// Method instance dipanggil lewat objek hasil new
Pemain budi = new Pemain("Budi");
Pemain siti = new Pemain("Siti");
budi.tambahSkor(10);
siti.tambahSkor(7);
budi.tambahSkor(5);
System.out.println(budi.laporan());
System.out.println(siti.laporan());
}
}Output yang Dihasilkan:
100.0 C = 212.0 F
212.0 F = 100.0 C
Budi : 15 poin
Siti : 7 poinPerbedaan perilakunya terlihat pada dua baris terakhir keluaran. Objek budi dan siti dibuat dari class Pemain yang sama, tetapi pemanggilan budi.tambahSkor(10) hanya menaikkan skor milik Budi — kata kunci this di dalam tambahSkor menunjuk objek pemanggil, sehingga siti tidak terpengaruh. Skor akhir Budi 15 dan Siti 7 berasal dari dua state yang terpisah, dikelola oleh method instance yang sama.
Ringkasan perbedaan keduanya dapat dipetakan demikian:
| Aspek | Method static | Method instance |
|---|---|---|
| Pemilik | Class | Setiap objek dari class |
| Cara memanggil | NamaClass.method(...) | objek.method(...) |
Butuh new? | Tidak | Ya |
| Akses field instance | Tidak bisa | Bisa, lewat this |
| Akses field/method static | Bisa | Bisa |
| Contoh di atas | Suhu.celsiusKeFahrenheit | budi.tambahSkor(10) |
Static Tidak Melihat State Objek #
Batas paling sering menyengat pemula: method static berjalan tanpa objek, sehingga tidak ada objek yang field-nya bisa dibaca. Compiler javac menolak setiap upaya method static menyentuh member instance:
public class AksesStaticSalah {
// Variabel instance: milik setiap objek AksesStaticSalah
String nama = "Budi";
// Method static berjalan tanpa objek, sehingga tidak melihat field nama
static void tampilkan() {
System.out.println(nama);
}
public static void main(String[] args) {
tampilkan();
}
}Compiler javac menolak dengan error: non-static variable nama cannot be referenced from a static context. Pesan ini beralasan penuh: field nama lahir bersama objek dan setiap objek bisa menyimpan nama berbeda — sedangkan pemanggilan tampilkan() berjalan tanpa objek mana pun, jadi tidak ada nama yang layak dibaca. Arah sebaliknya justru bebas: method instance boleh memanggil method static dan membaca field static, karena saat objek ada, class pasti sudah dimuat lebih dulu. Inilah alasan seluruh contoh awal Section ini memakai modifier static — agar method pembanding sederhana bisa dipanggil langsung dari main.
Dengan kepemilikan method beres, satu urusan tinggal: sampai sejauh mana nama variabel terlihat di dalam method? Variabel lokal, parameter, field, dan blok bersarang punya aturan cakupan masing-masing — pembahasan lengkapnya ada pada Chapter Method Scope.
Referensi #
- JLS SE25 §8.4.3.2: static Methods
- Java API: java.lang.Math (contoh class berisi method static)
- dev.java: Belajar Java
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
AksesStaticSalah.java
Unduh berkaspublic class AksesStaticSalah {
// Variabel instance: milik setiap objek AksesStaticSalah
String nama = "Budi";
// Method static berjalan tanpa objek, sehingga tidak melihat field nama
static void tampilkan() {
System.out.println(nama);
}
public static void main(String[] args) {
tampilkan();
}
}
ArenaPemain.java
Unduh berkaspublic class ArenaPemain {
public static void main(String[] args) {
// Method static dipanggil lewat nama class, tanpa instans
System.out.println("100.0 C = " + Suhu.celsiusKeFahrenheit(100.0) + " F");
System.out.println("212.0 F = " + Suhu.fahrenheitKeCelsius(212.0) + " C");
// Method instance dipanggil lewat objek hasil new
Pemain budi = new Pemain("Budi");
Pemain siti = new Pemain("Siti");
budi.tambahSkor(10);
siti.tambahSkor(7);
budi.tambahSkor(5);
System.out.println(budi.laporan());
System.out.println(siti.laporan());
}
}
Pemain.java
Unduh berkaspublic class Pemain {
// State milik tiap objek Pemain
String nama;
int skor;
Pemain(String nama) {
this.nama = nama;
this.skor = 0;
}
// Method instance: membaca dan menulis state objek yang memanggilnya
void tambahSkor(int poin) {
this.skor = this.skor + poin;
}
String laporan() {
return nama + " : " + skor + " poin";
}
}
Suhu.java
Unduh berkaspublic class Suhu {
// Method static: milik class, dipanggil tanpa membuat objek
static double celsiusKeFahrenheit(double celsius) {
return celsius * 9.0 / 5.0 + 32.0;
}
static double fahrenheitKeCelsius(double fahrenheit) {
return (fahrenheit - 32.0) * 5.0 / 9.0;
}
}