Kita perlu membedakan dua aspek konstanta:
- nama untuk nilai yang dikenal pada waktu pengembangan, yang kami perkenalkan untuk pemeliharaan yang lebih baik, dan
- nilai-nilai yang tersedia untuk kompiler.
Dan kemudian ada jenis ketiga terkait: variabel yang nilainya tidak berubah, yaitu nama untuk nilai. Perbedaan antara variabel yang tidak berubah ini dan konstanta adalah ketika nilai ditentukan / ditugaskan / diinisialisasi: variabel diinisialisasi pada saat runtime, tetapi nilai konstanta diketahui selama pengembangan. Perbedaan ini agak berlumpur karena nilai dapat diketahui selama pengembangan tetapi sebenarnya hanya dibuat selama inisialisasi.
Tetapi jika nilai konstanta diketahui pada waktu kompilasi, maka kompiler dapat melakukan perhitungan dengan nilai itu. Sebagai contoh, bahasa Jawa memiliki konsep ekspresi konstan . Ekspresi konstan adalah ekspresi apa pun yang hanya terdiri dari literal primitif atau string, operasi pada ekspresi konstan (seperti casting, penambahan, penggabungan string), dan variabel konstan. [ JLS §15.28 ] Variabel konstan adalah final
variabel yang diinisialisasi dengan ekspresi konstan. [JLS §4.12.4] Jadi untuk Java, ini adalah konstanta waktu kompilasi:
public static final int X = 7;
Ini menjadi menarik ketika variabel konstan digunakan dalam beberapa unit kompilasi, dan kemudian deklarasi diubah. Mempertimbangkan:
Sekarang ketika kita mengkompilasi file-file ini B.class
bytecode akan mendeklarasikan sebuah field Y = 9
karena B.Y
merupakan variabel konstan.
Tetapi ketika kita mengubah A.X
variabel ke nilai yang berbeda (katakanlah X = 0
) dan hanya mengkompilasi ulang A.java
file, maka B.Y
masih mengacu pada nilai yang lama. Keadaan A.X = 0, B.Y = 9
ini tidak konsisten dengan deklarasi dalam kode sumber. Selamat men-debug!
Ini tidak berarti bahwa konstanta tidak boleh diubah. Konstanta secara definitif lebih baik daripada angka ajaib yang muncul tanpa penjelasan dalam kode sumber. Namun, yang nilai dari konstanta publik merupakan bagian dari API publik Anda . Ini tidak khusus untuk Java, tetapi juga terjadi di C ++ dan bahasa lain yang menampilkan unit kompilasi terpisah. Jika Anda mengubah nilai-nilai ini, Anda harus mengkompilasi ulang semua kode dependen, yaitu melakukan kompilasi bersih.
Tergantung pada sifat konstanta, mereka mungkin menyebabkan asumsi yang salah oleh pengembang. Jika nilai-nilai ini diubah, mereka dapat memicu bug. Sebagai contoh, satu set konstanta dapat dipilih sehingga mereka membentuk pola bit tertentu, misalnya public static final int R = 4, W = 2, X = 1
. Jika ini diubah untuk membentuk struktur yang berbeda seperti R = 0, W = 1, X = 2
maka kode yang ada seperti boolean canRead = perms & R
menjadi salah. Dan pikirkan kesenangan yang akan terjadi kemudian Integer.MAX_VALUE
berubah! Tidak ada perbaikan di sini, hanya penting untuk diingat bahwa nilai beberapa konstanta benar-benar penting dan tidak dapat diubah secara sederhana.
Tetapi untuk mayoritas konstanta yang mengubahnya akan baik-baik saja selama pembatasan di atas dipertimbangkan. Konstanta aman untuk diubah ketika maknanya, bukan nilai spesifik yang penting. Ini adalah contoh kasus untuk merdu seperti BORDER_WIDTH = 2
atau TIMEOUT = 60; // seconds
atau template seperti API_ENDPOINT = "https://api.example.com/v2/"
- meskipun bisa dibilang beberapa atau semua dari mereka harus ditentukan dalam file konfigurasi daripada kode.