Değişken Kapsamı (Variable Scope)
Bir değişkenin kapsamı (scope), ona nereden erişilebileceğini ve ne kadar süre yaşayacağını belirler. Yanlış kapsam seçimi, "değişken bulunamıyor" derleme hatalarından, "değer beklediğim gibi değişmedi" mantık hatalar…
Değişken Kapsamı (Variable Scope)
Bir değişkenin kapsamı (scope), ona nereden erişilebileceğini ve ne kadar süre yaşayacağını belirler. Yanlış kapsam seçimi, "değişken bulunamıyor" derleme hatalarından, "değer beklediğim gibi değişmedi" mantık hatalarına kadar birçok soruna yol açar. Java'da dört temel değişken türü ve kapsamı vardır; bunları net ayırmak temiz ve hatasız kod yazmanın anahtarıdır.
Dört değişken türü ve kapsamı
| Tür | Nerede tanımlı | Kapsam (erişim) | Ömür | Varsayılan değer |
|---|---|---|---|---|
| Yerel (local) | Metot/yapıcı içinde | Yalnızca o metot | Metot çağrısı boyunca | Yok (atanmalı) |
| Blok | { } içinde (for/if...) | Yalnızca o blok | Blok boyunca | Yok (atanmalı) |
| Örnek (instance) | Sınıf gövdesinde (static değil) | Tüm sınıf (nesne üzerinden) | Nesne yaşadıkça | Var (0/null/false) |
| Statik (static) | Sınıf gövdesinde (static) | Tüm sınıf (paylaşılan) | Program boyunca | Var (0/null/false) |
class Sayac { static int toplam; // STATİK: tüm nesneler paylaşır (tek kopya) int deger; // ÖRNEK: her nesnenin kendi kopyası void m() { int yerel = 5; // YEREL: yalnızca m() içinde for (int i = 0; i < 3; i++) { int blok = i; // BLOK: yalnızca döngü içinde } // i ve blok burada ERİŞİLEMEZ } }
Örnek 1 (./Ornek1.java) dört türü birlikte gösterir: statik alan paylaşılır (sayaç),
örnek alanı nesneye özeldir, yerel/blok değişkenleri dar kapsamlıdır.
Önemli fark: Yerel değişkenlerin varsayılan değeri yoktur — kullanmadan önce atanmalıdır (yoksa derleme hatası). Alanlar (instance/static) ise otomatik varsayılan alır (sayılar 0, nesneler null, boolean false).
Gölgeleme (shadowing)
Bir yerel değişken veya parametre, aynı isimli bir alanla aynı kapsamdaysa onu gölgeler:
o isim artık yereli gösterir. Alana erişmek için this. gerekir:
class Kisi { private int yas; void setYas(int yas) { // parametre 'yas', alanı gölgeler this.yas = yas; // this.yas = ALAN, yas = PARAMETRE } }
Klasik hata:
thisunutmak.yas = yas;parametreyi kendine atar — alan değişmez! Doğrusuthis.yas = yas;. Bu, setter/constructor'larda en sık yapılan hatalardandır (IDE'ler uyarır). Örnek 2 (./Ornek2.java) bu tuzağı canlı gösterir.
İki yerel değişken aynı kapsamda aynı ada sahip olamaz (derleme hatası). Gölgeleme yalnızca yerel/parametre ↔ alan arasında olur.
İyi uygulamalar
- En dar kapsamı kullan: Değişkeni, kullanılacağı yere en yakın tanımla (mümkünse blok içinde). Bu, okunabilirliği artırır ve hataları azaltır.
- Gölgelemeyi bilinçli kullan (constructor/setter parametreleri için yaygın) ve her zaman
this.ile alana eriş. - Statik durumdan kaçın: Paylaşılan değiştirilebilir statik alanlar, çok thread'li ortamda yarış koşullarına ve test zorluğuna yol açar (gerçekten paylaşılması gerekmiyorsa örnek alanı kullan).
Özet
Dört değişken türünü ve kapsamlarını — yerel, blok, örnek (instance), statik — ömürleri ve
varsayılan değerleriyle (Örnek 1); gölgeleme (shadowing) kavramını ve this unutma tuzağını
(Örnek 2) öğrendik; "en dar kapsam" ilkesini ve statik durum uyarısını gördük. Sırada, nesneleri
doğru başlatmanın yolu: constructor'lar.
▶ Kod Örnekleri(2)
Ornek1
çalıştırılabilir1// Ornek1: Değişken kapsamları — yerel, örnek (instance), statik ve blok kapsamı.
2// Çalıştırma: java Ornek1.java
3public class Ornek1 {
4
5 static int statikSayac = 0; // STATİK alan: sınıfa ait, TÜM nesneler paylaşır (tek kopya).
6
7 int ornekDeger; // ÖRNEK (instance) alanı: her nesnenin KENDİ kopyası var.
8
9 Ornek1(int deger) {
10 this.ornekDeger = deger;
11 statikSayac++; // her nesne oluşturulduğunda paylaşılan sayaç artar
12 }
13
14 void metot() {
15 int yerel = 100; // YEREL değişken: yalnızca bu metot içinde yaşar.
16 System.out.println(" yerel=" + yerel + ", ornekDeger=" + ornekDeger + ", statikSayac=" + statikSayac);
17
18 // BLOK kapsamı: { } içinde tanımlanan değişken yalnızca o blokta görünür.
19 for (int i = 0; i < 3; i++) {
20 int blokDegiskeni = i * 10; // her tur yeniden oluşur, döngü dışında ERİŞİLEMEZ
21 System.out.print(" blok: i=" + i + " blokDegiskeni=" + blokDegiskeni + "; ");
22 }
23 System.out.println();
24 // System.out.println(i); // HATA: i döngü bloğunun dışında görünmez
25 // System.out.println(blokDegiskeni); // HATA: blok dışında erişilemez
26 }
27
28 public static void main(String[] args) {
29 Ornek1 a = new Ornek1(10);
30 Ornek1 b = new Ornek1(20);
31
32 System.out.println("a.ornekDeger=" + a.ornekDeger + " (a'ya özel)");
33 System.out.println("b.ornekDeger=" + b.ornekDeger + " (b'ye özel — ayrı kopya)");
34 System.out.println("statikSayac=" + Ornek1.statikSayac + " (paylaşılan: 2 nesne yaratıldı)");
35
36 System.out.println("\na.metot():"); a.metot();
37
38 System.out.println("""
39
40 --- Değişken kapsamları (scope) ---
41 YEREL (local): metot/yapıcı içinde; yalnızca orada yaşar; her çağrıda yeniden oluşur; varsayılan değeri YOK (atanmalı).
42 BLOK: { } içinde (for/if/while gövdesi); yalnızca o blokta görünür.
43 ÖRNEK (instance) alanı: her NESNENİN kendi kopyası; nesne yaşadıkça yaşar; varsayılan değer alır (0/null/false).
44 STATİK alan: SINIFA ait, tüm nesneler PAYLAŞIR (tek kopya); program boyunca yaşar.
45 Kural: en dar kapsamı kullan; değişkeni gerektiği yere en yakın tanımla (okunabilirlik + hata azalır).""");
46 }
47}Ornek2
çalıştırılabilir1// Ornek2: Gölgeleme (shadowing) — aynı isimli yerel/parametre değişkeni, alanı "gölgeler".
2// Çalıştırma: java Ornek2.java
3public class Ornek2 {
4
5 static class Kisi {
6 private String ad; // örnek alanı
7 private int yas;
8
9 // Parametre adları alanlarla AYNI -> parametreler alanları GÖLGELER.
10 Kisi(String ad, int yas) {
11 // 'ad' burada PARAMETREyi gösterir (alanı değil). Alana erişmek için 'this.' ŞART.
12 this.ad = ad; // this.ad = alan, ad = parametre
13 this.yas = yas;
14 }
15
16 void yanlisAtama(int yas) {
17 // this OLMADAN: 'yas = yas' kendine atama -> alan DEĞİŞMEZ (sık yapılan hata!)
18 yas = yas; // etkisiz
19 }
20
21 void dogruAtama(int yas) {
22 this.yas = yas; // this ile alan güncellenir
23 }
24
25 @Override public String toString() { return ad + " (" + yas + ")"; }
26 }
27
28 public static void main(String[] args) {
29 Kisi k = new Kisi("Ada", 30);
30 System.out.println("Başlangıç: " + k);
31
32 k.yanlisAtama(99);
33 System.out.println("yanlisAtama(99) sonrası: " + k + " (this yok -> DEĞİŞMEDİ)");
34
35 k.dogruAtama(99);
36 System.out.println("dogruAtama(99) sonrası : " + k + " (this ile -> güncellendi)");
37
38 // Blok gölgeleme: Java'da yerel değişken, başka bir YEREL değişkeni gölgeleyemez (derleme hatası);
39 // ancak yerel değişken bir ALANI gölgeleyebilir.
40 System.out.println("""
41
42 --- Gölgeleme (shadowing) ---
43 Bir yerel değişken/parametre, aynı isimli bir ALANLA aynı kapsamdaysa onu 'gölgeler':
44 o isim artık YEREL olanı gösterir; alana erişmek için 'this.alan' kullanılır.
45 KLASİK HATA: constructor/setter'da 'yas = yas' -> parametreyi kendine atar, ALAN değişmez!
46 Doğrusu: 'this.yas = yas;'. (IDE'ler bunu uyarır.)
47 NOT: iki YEREL değişken aynı kapsamda aynı ada sahip OLAMAZ (derleme hatası); gölgeleme yalnızca alan-yerel arasında olur.
48 İyi pratik: gölgelemeyi bilinçli kullan (constructor parametreleri) ve her zaman 'this.' ile netleştir.""");
49 }
50}