Java Integer Cache
Java programlama yapanlar, sık sık 2 değişkeni karşılaştırma ihtiyacı duyarlar. 2 değişken karşılaştırılırken == operatörü kullanılır. Bu operatör, true veya false sonucu verir. Karşılaştırdığımız değişkenler eşitse true, eşit değilse false sonucu elde edilir.
Örnek vermek gerekirse;
int a = 1;
int b = 1;
if (a == b) {
System.out.println("a değişkeni, b değişkenine eşittir.");
} else {
System.out.println("a değişkeni, b değişkenine eşit değildir.");
}
Integer Cache konusuna girmeden önce Java'da kullanılan int ve Integer'ın farklı kavramlar olduğunu bilmemiz gerekmektedir.
int, "Primitive Type" kapsamındadır. (short, double, char, float, boolean, byte Java'daki diğer "Primitive Type" kavramlarıdır.)
2 int değişken karşılaştırıldığında sadece değer karşılaştırması yapılır. Böylece, 2 int değişkeninin değeri eşitse == operatörü ile yapılan karşılaştırmanın sonucu true olarak elde edilir.
Integer ise bir sınıftır, "Primitive Type" değildir. Integer, Double, Long vb. sınıflar, "Reference Type" ve "Wrapper Class" olarak da adlandırılmaktadır.
Bunlar, nesnenin kendisi yerine hafızadaki adresini tutar.
Örnek vermek gerekirse,
Integer a = new Integer(1); //1 değerinin saklandığı hafıza adresi tutulur. (new ile oluşturulduğundan hafızada yeni bir yer ayrılır.)
Integer b = new Integer(1); //1 değerinin saklandığı hafıza adresi tutulur. (new ile oluşturulduğundan hafızada yeni bir yer ayrılır.)
Integer a = 10; //compiler bu satırı Integer a = Integer.valueOf(10); şeklinde, valueOf fonksiyonunu kullanarak çalıştırır.
int a = 128;
int b = 128;
Bu durumda ise a==b karşılaştırması true sonucunu verir. Çünkü valueOf gibi bir fonksiyon kullanılmaz. Doğrudan değerler karşılaştılır. "Primitive Type" kullandığımızda
değer ne olursa olsun iki değer eşitse == operatörü ile yapılan karşılaştırmalar true sonucunu verir.
Integer a = 127;
Integer b = 127;
Bu durumda a == b karşılaştırması true sonucunu verir.
Integer a = 128;
Integer b = 128;
Bu durumda a==b karşılaştırması false sonucunu verir.
"Wrapper Class" olan Integer ile çalışırken 127 değeri atandığında true, 128 değeri atandığında false sonucu alındığını gördük. Peki bunun sebebi nedir?
Bunun sebebi "Integer Cache"'tir. Integer sınıfında -128 ile 127 arasındaki değerler bir "Integer Cache"'te tutulur. Bu değerler, hafızaya yerleştirildikten sonra "Integer Cache"'te saklanır. Aynı değer farklı bir Integer değişkenine atandığında hafızada yeni bir yer açılmaz, "Integer Cache"'te tutulan eski değişken kullanılır. Bu da sık kullanılan -128 ile 127 arasındaki değerler her kullanıldığında hafızada yeni bir yer açılmamasını sağlar. Hafızadan kazanç sağlanır.
Integer sınıfındaki valueOf fonksiyonu aşağıdaki gibidir:
public static Integer valueOf(int i) {
if (i >= Integer.IntegerCache.low && i <= Integer.IntegerCache.high) {
return Integer.IntegerCache.cache[i + 128];
}
new Integer(i);
}
Görüldüğü gibi Integer.IntegerCache.low (-128)'dan büyük veya eşit ve Integer.IntegerCache.high (127)'tan küçük veya eşit bir değer gelmişse "Integer Cache" kullanılmaktadır.
Kaynaklar
1. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html
2. https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html