Anggota static

Menyimpan data dan perilaku tingkat kelas dengan field static, metode static, dan blok static.

Daftar isi

Anggota static adalah field, metode, maupun blok yang melekat pada kelasnya, bukan pada tiap objek. Data semacam ini cukup tersimpan satu salinan sepanjang program berjalan dan dapat diakses tanpa membuat satu objek pun. Topik ini memakai tiga contoh yang dapat dijalankan untuk membedakan field static dari field instansi, menunjukkan metode static sebagai utilitas, serta melacak kapan blok static dieksekusi.

Field static milik kelas#

Field yang diberi kata kunci static hidup di tingkat kelas, sehingga seluruh objek kelas tersebut berbagi satu nilai yang sama. Kasus yang paling sering ditemui adalah pencacah, misalnya menghitung berapa banyak objek Penghitung yang pernah dibuat. Setiap objek tetap memiliki field instansi miliknya sendiri, sedangkan field static hanya ada satu.

java UjiPenghitung.java
public class UjiPenghitung {

    public static void main(String[] args) {
        Penghitung p1 = new Penghitung();
        Penghitung p2 = new Penghitung();
        Penghitung p3 = new Penghitung();
        System.out.println("Seri p1 : " + p1.nomorSeri);
        System.out.println("Seri p2 : " + p2.nomorSeri);
        System.out.println("Seri p3 : " + p3.nomorSeri);
        System.out.println("Total objek dibuat : " + Penghitung.totalDibuat);
    }
}

class Penghitung {
    static int totalDibuat;
    int nomorSeri;

    Penghitung() {
        totalDibuat++;
        nomorSeri = totalDibuat;
    }
}
text Keluaran
Seri p1 : 1
Seri p2 : 2
Seri p3 : 3
Total objek dibuat : 3

Konstruktor menaikkan totalDibuat setiap kali objek lahir, lalu menyalin angkanya ke nomorSeri milik objek baru. Ketiga objek menyimpan seri yang berbeda karena nomorSeri adalah field instansi, tetapi ketiganya membaca dan menaikkan satu totalDibuat yang sama karena field itu static. Cara pemanggilannya juga berbeda, yaitu lewat nama kelas Penghitung.totalDibuat, karena nilai tersebut tidak melekat pada p1, p2, maupun p3.

kelas Penghitungstatic totalDibuat = 3satu salinan, dibagi semua objeknomorSerimilik tiap objekmembaca nilai yang samaobjek p1nomorSeri = 1objek p2nomorSeri = 2objek p3nomorSeri = 3
Satu field static dibagi semua objek, sedangkan field instansi dimiliki tiap objek

Metode static#

Metode static sama-sama melekat pada kelas dan dipanggil lewat nama kelasnya tanpa membuat objek. Metode ini tepat untuk pekerjaan yang seluruh masukannya berasal dari parameter, tanpa menyentuh field instansi. Contoh klasiknya ada di kelas bawaan Java, misalnya Math.sqrt(25) dan Integer.parseInt("42"), yang keduanya tidak memerlukan objek Math atau Integer untuk dipanggil.

java UjiKonversi.java
public class UjiKonversi {

    public static void main(String[] args) {
        System.out.println("212 F = " + Konversi.keCelsius(212) + " C");
        System.out.println("68 F  = " + Konversi.keCelsius(68) + " C");
        System.out.println("32 F  = " + Konversi.keCelsius(32) + " C");
    }
}

class Konversi {

    static double keCelsius(double fahrenheit) {
        return (fahrenheit - 32) / 1.8;
    }
}
text Keluaran
212 F = 100.0 C
68 F  = 20.0 C
32 F  = 0.0 C

Kelas Konversi tidak pernah dibuat objeknya, dan memang tidak ada field instansi yang perlu disimpan, sehingga metode keCelsius cukup dipanggil sebagai Konversi.keCelsius(...). Batasannya penting diingat, yaitu metode static tidak dapat memakai this, memanggil metode instansi, atau membaca field instansi secara langsung, karena pemanggilannya tidak menyertakan objek pemanggil. Bila sebuah metode membutuhkan keadaan objek, metode itu haruslah metode instansi.

Blok static#

Blok static adalah potongan kode yang diberi kata kunci static lalu dibungkus kurung kurawal, ditempatkan di dalam kelas tanpa nama maupun parameter. Blok ini dijalankan tepat satu kali, yaitu saat kelas dimuat dan diinisialisasi oleh JVM, lebih dulu daripada pemakaian anggota static mana pun. Tempat yang cocok untuknya adalah penyiapan nilai awal yang membutuhkan lebih dari satu pernyataan.

java UjiBlokStatic.java
public class UjiBlokStatic {

    public static void main(String[] args) {
        System.out.println("Program dimulai");
        System.out.println("Batas   : " + Konfigurasi.BATAS);
        System.out.println("Folder  : " + Konfigurasi.FOLDER);
    }
}

class Konfigurasi {
    static int BATAS;
    static String FOLDER;

    static {
        System.out.println("Blok static dijalankan");
        BATAS = 100;
        FOLDER = "arsip";
    }
}
text Keluaran
Program dimulai
Blok static dijalankan
Batas   : 100
Folder  : arsip

Urutan keluarannya menyimpan pelajaran tersendiri. Baris “Program dimulai” dicetak lebih dulu karena main memang berjalan sebelum ada pemakaian Konfigurasi. Kelas baru diinisialisasi ketika pernyataan Konfigurasi.BATAS dieksekusi, sehingga blok static berjalan pada titik itu, mencetak baris keduanya, dan mengisi kedua field sebelum nilainya dibaca. Blok tidak berjalan lagi meskipun anggota static diakses berkali-kali setelahnya.

Kapan static dipakai#

Tiga pemakaian static yang paling aman adalah konstanta bersama, utilitas murni atas parameter, dan pencacah tingkat kelas seperti pada Penghitung. Ketiganya tidak menuntut keadaan yang berubah di tengah jalan, sehingga tidak menimbulkan kejutan bagi pembaca kode. Penulisan konstantanya biasa mengikuti kebiasaan huruf kapital dengan pemisah garis bawah, misalnya BATAS_MAKSIMAL, dan sering digabung dengan kata kunci final agar nilainya terkunci.

Field static yang bisa berubah adalah area yang paling perlu diwaspadai, karena sifatnya sama dengan variabel global yang dapat ditulis dari mana saja. Satu bagian program yang menaikkan nilainya langsung terlihat oleh seluruh bagian lain, dan saat nilai itu ternyata keliru, pelacakan penyebabnya menyeberangi banyak berkas. Pada program dengan banyak thread, penulisan serempak ke field static semacam ini juga menjadi sumber bug yang sulit diungkap.

Kesalahan umum#

  • Memanggil anggota static lewat referensi objek, misalnya p1.totalDibuat. Kode itu berjalan, tetapi mengesankan nilai tersebut milik p1, padahal yang dibaca kompilator hanyalah tipe variabelnya. Tulis Penghitung.totalDibuat.
  • Membuat metode static yang membutuhkan data objek. Metode semacam ini tidak punya akses ke field instansi dan paksaan mengisinya lewat parameter biasanya menandakan metode itu seharusnya metode instansi.
  • Menganggap field static tersalin ke setiap objek. Nilainya satu dan dibagi, sehingga perubahan lewat satu jalur langsung terbaca dari semua jalur lain.
  • Menumpuk logika inisialisasi kompleks pada blok static. Blok yang panjang dan bergantung pada urutan pemanggilan kelas sulit diperkirakan, sehingga penyiapan semacam ini lebih baik diletakkan di metode yang dipanggil secara sadar.

Ringkasan#

  • Anggota static melekat pada kelas, tersimpan satu salinan, dan diakses lewat nama kelas tanpa membuat objek.
  • Field static cocok untuk pencacah dan konstanta bersama, sedangkan field instansi tetap milik tiap objek.
  • Metode static bekerja murni atas parameter karena tidak menyertakan objek pemanggil, sehingga tidak dapat memakai this atau field instansi.
  • Blok static dijalankan sekali ketika kelas diinisialisasi, tepat sebelum anggota static pertama kali dipakai.

Referensi#