Her şeyden önce, sadece yerel değişkenlerden bahsediyoruz . Etkili olarak nihai alanlar için geçerli değildir. final
Alanlar için anlambilim çok farklı olduğundan ve yoğun derleyici optimizasyonlarına ve bellek modeli vaatlerine tabi olduğundan , bu önemlidir, son alanların anlambilimiyle ilgili 17.5.1 $ 'a bakın .
Yüzey seviyesinde final
ve effectively final
yerel değişkenler için gerçekten aynıdır. Bununla birlikte, JLS, bu gibi özel durumlarda aslında geniş bir etki yelpazesine sahip olan ikisi arasında net bir ayrım yapar.
Öncül
Gönderen JLS§4.12.4 hakkında final
değişkenler:
Bir sürekli değişken bir bir final
değişken basit tür ve tip dize bir başlatılır sabit ekspresyon ( §15.29 ). Bir değişkenin sabit bir değişken olup olmaması , sınıf başlatma ( §12.4.1 ), ikili uyumluluk ( §13.1 ), erişilebilirlik ( §14.22 ) ve kesin atama ( §16.1.1 ) ile ilgili sonuçlara sahip olabilir .
Yana int
ilkel, değişken a
bir olan sabit bir değişken .
Ayrıca, aynı bölümden şu konu hakkında effectively final
:
Nihai olarak beyan edilmeyen bazı değişkenler bunun yerine etkili bir şekilde nihai kabul edilir:
Bu ifadeli şeklinden itibaren Yani, diğer örnekte, açıktır a
edilir değil , olduğu gibi, sabit bir değişken olarak kabul nihai değil , ama sadece etkili bir şekilde nihai.
Davranış
Artık ayrımı bildiğimize göre, neler olup bittiğine ve çıktının neden farklı olduğuna bakalım.
? :
Burada koşullu operatörü kullanıyorsunuz , bu yüzden tanımını kontrol etmeliyiz. Gönderen JLS§15.25 :
İkinci ve üçüncü işlenen ifadelerine göre sınıflandırılan üç tür koşullu ifade vardır: boole koşullu ifadeler , sayısal koşullu ifadeler ve referans koşullu ifadeler .
Bu durumda, bir bahsediyoruz sayısal koşullu ifadelerde gelen, JLS§15.25.2 :
Sayısal bir koşullu ifadenin türü şu şekilde belirlenir:
Ve bu, iki vakanın farklı şekilde sınıflandırıldığı kısımdır.
etkili bir şekilde son
effectively final
Bu kuralla eşleşen sürüm :
Aksi takdirde, ikinci ve üçüncü işlenenlere genel sayısal yükseltme ( §5.6 ) uygulanır ve koşullu ifadenin türü, ikinci ve üçüncü işlenenlerin yükseltilmiş türüdür.
Yapacağınla aynı davranış 5 + 'd'
, yani int + char
sonuçlanan int
. Bkz. JLS§5.6
Sayısal yükseltme, sayısal bir bağlamdaki tüm ifadelerin yükseltilen türünü belirler. Yükseltilmiş tip, her bir ifade yükseltilmiş türe dönüştürülebilecek şekilde seçilir ve bir aritmetik işlem durumunda işlem, yükseltilmiş tipin değerleri için tanımlanır. Sayısal bağlamdaki ifadelerin sırası, sayısal yükseltme için önemli değildir. Kurallar aşağıdaki gibidir:
[...]
Daha sonra, genişleyen ilkel dönüştürme ( §5.1.2 ) ve daraltma ilkel dönüştürme ( §5.1.3 ), aşağıdaki kurallara göre bazı ifadelere uygulanır:
Sayısal seçim bağlamında, aşağıdaki kurallar geçerlidir:
Herhangi bir ifade tipi ise int
ve bir sabit bir ifade değildir ( §15.29 ), daha sonra terfi türüdür int
, ve tip olmayan diğer ifadeler int
tabi ilkel dönüşüm genişletme için int
.
Yani her şey zaten olduğu int
gibi yükseltilir . Bu çıktıyı açıklıyor .a
int
97
final
final
Değişkeni içeren sürüm bu kuralla eşleşir:
İşlenen bir tip ise, T
burada T
olduğu byte
, short
ya da char
, ve diğer işlenen bir sabit ifadesi ( §15.29 tipte) int
değer türü sunulabilen T
, koşullu ekspresyonu türüdür T
.
Son değişken a
tiptedir int
ve sabit bir ifadedir (çünkü öyle final
). Sonuç olarak gösterilebilir char
, dolayısıyla sonuç türdendir char
. Bu çıktıyı tamamlıyor a
.
Dize örneği
Dize eşitliği örneği, aynı çekirdek farkına dayanmaktadır, final
değişkenler sabit ifade / değişken olarak değerlendirilir ve effectively final
değildir.
Java'da dize interneti sabit ifadelere dayalıdır, dolayısıyla
"a" + "b" + "c" == "abc"
olduğu true
(gerçek kodda bu yapının kullanılmasına daha dont) de.
Bkz. JLS§3.10.5 :
Dahası, bir dize değişmezi her zaman aynı String sınıfına başvurur. Bunun nedeni, dize değişmezlerinin - veya daha genel olarak , sabit ifadelerin ( §15.29 ) değerleri olan dizelerin - yöntemi ( §12.5 ) kullanarak benzersiz örnekleri paylaşmak için "dahil edilmesidir " .String.intern
Öncelikle değişmezlerden bahsedildiği için gözden kaçırılması kolaydır, ancak aslında sabit ifadeler için de geçerlidir.