Sabitlerin iki yönünü ayırt etmemiz gerekir:
- Geliştirme zamanında bilinen ve daha iyi korunma amacıyla verdiğimiz değerler için isimler ve
- derleyici için mevcut değerler.
Ve bununla ilgili üçüncü tür bir tür var: değeri değişmeyen değişkenler, yani bir değerin adları. Bu değişmez değişkenler ile bir sabit arasındaki fark, değerin belirlendiği / atandığı / başlatıldığı zamandır: değişken, çalışma zamanında başlatılır, ancak geliştirme sırasında bir sabitin değeri bilinir. Bu ayrım biraz çamurludur, çünkü geliştirme sırasında bir değer bilinebilir, ancak aslında yalnızca başlatma sırasında yaratılır.
Ancak bir sabitin değeri derleme zamanında biliniyorsa, derleyici bu değerle hesaplamalar yapabilir. Örneğin, Java dili sabit ifadeler kavramına sahiptir . Sabit ifade, yalnızca ilkel veya dizgenin değişmezlerinden, sabit ifadelerdeki işlemlerden (örneğin döküm, toplama, dize birleştirme) ve sabit değişkenlerden oluşan herhangi bir ifadedir. [ JLS §15.28 ] Sabit bir final
değişken, sabit bir ifadeyle başlatılan bir değişkendir. [JLS §4.12.4] Java için bu bir derleme zamanı sabitidir:
public static final int X = 7;
Birden fazla derleme ünitesinde sabit bir değişken kullanıldığında ve ardından bildirim değiştirildiğinde bu ilginç hale gelir. Düşünmek:
Şimdi bu dosyaları derlediğimizde B.class
bytecode bir alan ilan edecek Y = 9
çünkü B.Y
sabit bir değişken.
Ancak, A.X
değişkeni farklı bir değere (örneğin X = 0
) değiştirdiğimizde ve sadece A.java
dosyayı yeniden derlediğimizde , B.Y
hala eski değere işaret eder. Bu durum A.X = 0, B.Y = 9
kaynak kodundaki bildirimlerle tutarsız. Mutlu hata ayıklama!
Bu, sabitlerin asla değiştirilmemesi gerektiği anlamına gelmez. Sabitler, kaynak kodunda açıklama olmadan görünen sihirli sayılardan kesinlikle daha iyidir. Ancak, değer kamu sabitler genel API parçasıdır . Bu, Java'ya özgü değildir, ancak C ++ ve ayrı derleme birimleri içeren diğer dillerde de oluşur. Bu değerleri değiştirirseniz, tüm bağımlı kodları yeniden derlemeniz gerekecektir, yani temiz bir derleme yapmanız gerekecektir.
Sabitlerin niteliğine bağlı olarak, geliştiriciler tarafından yanlış varsayımlara yol açmış olabilirler. Bu değerler değiştirilirse, bir hata tetikleyebilir. Örneğin, belirli bit desenleri oluşturacak şekilde bir sabitler kümesi seçilebilir, örneğin public static final int R = 4, W = 2, X = 1
; Bunlar gibi farklı bir yapı oluşturacak şekilde değiştirilirse, R = 0, W = 1, X = 2
o zaman varolan kod boolean canRead = perms & R
yanlış olur. Ve sadece ortaya çıkacak eğlencenin Integer.MAX_VALUE
değişeceğini düşünün ! Burada bir düzeltme yok, bazı sabitlerin değerinin gerçekten önemli olduğunu ve basitçe değiştirilemeyeceğini unutmamak önemlidir.
Ancak, sabitlerin çoğunun değişmesi, yukarıdaki kısıtlamalar göz önüne alındığı sürece, iyi olacak. Belirli bir değerin değil, anlamın ne zaman önemli olduğu, değişmesi güvenlidir. Bu gibi tunables için durum örneğin edilir BORDER_WIDTH = 2
ya TIMEOUT = 60; // seconds
veya şablonlar gibi API_ENDPOINT = "https://api.example.com/v2/"
- gerçi muhtemelen bunlardan bazılarının veya tümünün yapılandırma dosyaları yerine kodunda belirtilen gerektiğini.