int ve Integer — Kutulu ve Kutusuz Sayılar
Önce şunu oku: Stack, Heap ve Pass-by-Value
30 saniyede özet
int sayının kendisi, Integer ise onun nesne kutusudur. Java ikisi arasında kendiliğinden çevirir; boş kutuyu açmak NullPointerException verir, == ise 127'den sonra şaşırtır.
Bir kuyumcuya yüzüğünü çıplak elinde de götürebilirsin, bir kutunun içinde de. Yüzük aynı yüzüktür; kutu sadece taşımayı ve saklamayı kolaylaştırır.
Java’da sayılar da böyledir: bazen çıplak, bazen bir kutunun içinde. Çoğu zaman farkı hiç hissetmezsin, ama birkaç yerde hissedersin.
Adım adım oku
- int x doğrudan 42 değerini tutuyor.
- Integer y ise 42'yi taşıyan bir nesneyi gösteriyor.
- Integer y = x yazınca Java sayıyı kendiliğinden bir kutuya koyar.
- int z = y yazınca da kutuyu kendiliğinden açar.
-
Bayt: Bakiyeyi map'ten okudum ve program NullPointerException ile durdu. Ortada nesne bile yoktu!
-
Sen: Bakiye int değil miydi?
-
Bayt: Değişken int, ama map'ten gelen Integer. Kutu boşmuş ve Java onu açmaya çalışmış.
-
Bayt: Kutulu ve kutusuz sayıları tanıyınca bu sürpriz bir daha olmaz.
İki tür sayı
int, long, double, boolean gibi tipler ilkel tiplerdir: sayının kendisini tutarlar ve hiçbir zaman null olamazlar.
Her birinin bir nesne karşılığı vardır: Integer, Long, Double, Boolean. Bunlara wrapper sınıfBir ilkel tipin nesne karşılığı: int için Integer, long için Long, boolean için Boolean. Koleksiyonlarda ve null gereken yerlerde kullanılır.Wrapper nesneleri değişmezdir ve null olabilir. Değerlerini karşılaştırmak için == değil equals kullanılır.Sözlükte gör → denir. Koleksiyonlar ve generics yalnızca nesne tuttuğu için List<int> yazamazsın; List<Integer> yazarsın.
int adet = 3; // sayının kendisi, null olamazInteger secimliAdet = null; // "henüz seçilmedi" anlamında null olabilirList<Integer> puanlar = List.of(4, 5, 3); // koleksiyonlar nesne isterKafam karıştı, daha basit anlat
Hesap yaparken çıplak sayı kullan: int, long. Bir listeye koyman ya da “değer yok” demen gerektiğinde kutulu hâlini kullan: Integer, Long.
Neden `List<int>` yazamazsın da `List<Integer>` yazarsın?
Otomatik paketleme
Java ikisi arasında senin yerine çevirir. Sayıyı kutuya koymaya autoboxingJava'nın bir ilkel sayıyı kendiliğinden wrapper nesnesine koyması (int → Integer). Tersine, kutudan çıkarmaya unboxing denir.Çevirme görünmezdir: null bir kutuyu açmak NullPointerException verir, döngüde yapılan her açma-kapama yeni nesne üretir.Sözlükte gör →, kutudan çıkarmaya unboxing denir. Bu çevirme görünmezdir, bu yüzden de sürprizleri görünmez gelir.
bakiyeler adlı map henüz boş. `int b = bakiyeler.get("ali");` satırı ne yapar? Cevabı göster
NullPointerException fırlatır. get bulunamayan anahtar için null döner. Java bu null kutuyu int’e çevirmek için açmaya çalışır ve içinde sayı yoktur.
Map.get, bir veritabanı sonucu ya da bir istek alanı null dönebiliyorsa, onu doğrudan bir int’e atamak tehlikelidir. Önce kontrol et ya da bir varsayılan ver: bakiyeler.getOrDefault("ali", 0).
Kafam karıştı, daha basit anlat
Kutu boş olabiliyorsa, açmadan önce içine bak. getOrDefault bunu senin yerine yapar: kutu boşsa sana verdiğin yedek sayıyı döndürür.
Program ne yapar?
Bir map'te bulunamayan anahtar için 0 almak istiyorsun. En temiz yol hangisi?
Satır satır: 127 ile 128
İki kutuyu == ile karşılaştırmak, iki kutunun aynı kutu olup olmadığını sorar. Java küçük sayıların kutularını önceden hazırlayıp paylaştığı için bu soru bazen tesadüfen doğru çıkar.
Aynı sayı, farklı kutu
Integer a = 127, b = 127;System.out.println(a == b);Integer c = 128, d = 128;System.out.println(c == d);System.out.println(c.equals(d));Debug
cache -128 ile 127 arasındaki sayıların kutuları hazırdır ve paylaşılır. a ile b aynı hazır kutuyu gösterir.
- a
- = @K127
- b
- = @K127
Sol/sağ ok tuşlarıyla da gezebilirsin.
Aynı sayı, aynı kutu mu?
Tohum 638354Hazır (paylaşılan) kutular: -128 … 127 · karşılaştırma: a == b
Oynat ya da adımla: her adımda bir sayı karşılaştırılır.
Şu an ne oldu?
a == b · hazır kutular -128…127
İki değişken aynı sayıyı tutuyor. Karşılaştırma ne diyecek?
Görevler0/3
127 eşit, 128 eşit değilaçık
İpucu
Varsayılan ayarlar yeter.
Kodu değiştirmeden 128’i eşit çıkaraçık
İpucu
JVM ayarına bak.
Altı sayının hepsinde doğru cevabı alaçık
İpucu
Sayıyı karşılaştır.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat.
==ile 127 ve -128 eşit çıktı; 128, 1000 ve -129 çıkmadı. - “-XX:AutoBoxCacheMax=1000”i aç. Kod aynı, ama 128 ve 1000 artık eşit. Sonuç bir JVM ayarına bağlı.
- “new Integer” seç. Hiçbiri eşit değil: her seferinde yeni bir kutu açıldı.
- “a.equals(b)” seç. Altı sayının hepsinde doğru cevap.
Program ne yazdırır?
Döngüde gizli kutular
Autoboxing görünmez olduğu için döngülerde fark edilmeden binlerce kutu açılabilir.
Long toplam = 0L; // kutulufor (long i = 0; i < 1_000_000; i++) { toplam += i; // her turda: kutuyu aç, topla, yeni kutu yap}
long toplam2 = 0L; // kutusuz: sadece toplarİlk döngü her turda yeni bir Long nesnesi üretir ve çöp toplayıcıya iş çıkarır. Hesap yaparken ilkel tipi kullan; kutuyu yalnızca gerçekten nesne gereken yerde kullan.
Kafam karıştı, daha basit anlat
Bir sayıyı her turda kutuya koyup çıkarmak, her adımda paketi açıp kapatmak gibidir. Hesap yaparken paketi hiç kapatma: long kullan.
`Long toplam = 0L;` ile bir milyon turluk bir döngüde `toplam += i;` yapmak neden yavaştır?
Bankada bu iki sayı türü yan yana yaşar: bir müşterinin seçimlik alanları null olabilir, ama hesaplamalar kutusuz yapılır.
Derinleş · Günlük limit: null olabilen ayar, kutusuz hesap 3 dosya · ~25 satır · ilk okumada atlayabilirsin
Tuzaklar
Wrapper’ları == ile karşılaştırmak. Test verisi küçük sayılar olduğu için testler geçer, gerçek verideki büyük sayılarda bozulur. Hep equals ya da Objects.equals kullan.
Üçlü ifadede gizli unboxing. Integer x = kosul ? map.get(k) : 0; satırında sonuç tipi int olur ve map.get(k) null ise yine NullPointerException gelir. Varsayılanı Integer.valueOf(0) yap ya da getOrDefault kullan.
new Integer(5) yazmak. Bu kurucu kullanımdan kaldırıldı. Integer.valueOf(5) ya da doğrudan 5 yaz; hazır kutular yeniden kullanılsın.
Bu metot, kampanya tanımlı olmayan müşterilerde NullPointerException atıyor. Hatanın kaynağı hangi satır?
Kendini sına
int bir değişken null olabilir.
Her değişkeni int (ilkel) ya da Integer (wrapper) olarak tutmanın uygun olduğuna göre ayır.
Aklında kalacak üç şey
- 1 int sayının kendisidir ve null olamaz; Integer aynı sayının kutusudur, koleksiyonlarda ve null olabilen yerlerde kullanılır.
- 2 Boş (null) bir Integer'ı int'e çevirmek NullPointerException verir; Map.get gibi null dönebilen yerler buna en açık kapıdır.
- 3 İki Integer'ı == ile değil equals ile karşılaştırırsın; == küçük sayılarda tesadüfen çalışır, 127'den sonra bozulur.
3 kart sonraki derste seni bekliyor