Eğitim Portalı/Java/Değişken Kapsamı (Variable Scope)
Java01-java/92-degisken-kapsami

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ürNerede tanımlıKapsam (erişim)ÖmürVarsayılan değer
Yerel (local)Metot/yapıcı içindeYalnızca o metotMetot çağrısı boyuncaYok (atanmalı)
Blok{ } içinde (for/if...)Yalnızca o blokBlok boyuncaYok (atanmalı)
Örnek (instance)Sınıf gövdesinde (static değil)Tüm sınıf (nesne üzerinden)Nesne yaşadıkçaVar (0/null/false)
Statik (static)Sınıf gövdesinde (static)Tüm sınıf (paylaşılan)Program boyuncaVar (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: this unutmak. yas = yas; parametreyi kendine atar — alan değişmez! Doğrusu this.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ılabilir
Ornek1.java
1// 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}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// 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}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.