Logo
Ana Sayfa
ÖZEL KODLAMA DERSLERİ
Yazılım Özel Ders
Tüm birebir programlara genel bakış
Python Yazılım Kursu
Sıfırdan ileri seviyeye birebir Python
Java Yazılım Kursu
OOP odaklı birebir Java eğitimi
AP Computer Science Principles
AP CSP sınav hazırlığı
GRUP DERSLERİ
Python & Django Masterclass
SINIRLI KONTENJAN
Java & Spring Boot Masterclass
SINIRLI KONTENJAN
C# .NET Masterclass
SINIRLI KONTENJAN
VİDEO DERSLER
Sıfırdan Temel Python Kursu
Kendi Hızında Öğren
ÜCRETSİZ
Seviye Testi
Ücretsiz — Python, Java, algoritma seviye testleri
Kariyerini Keşfet
Sertifika Doğrula
Belge numarası ve soyad ile doğrulama

Java'da Static ve Instance Değişken/Metot Farkı: 'Non-Static Variable' Hatası Nasıl Çözülür?

Yazar: Berk Keskin 28.08.2026 ~11 dk okuma 1 Okunma
java-static-instance-degisken-metot-farki

Java'da static ve instance (örnek) değişken/metot arasındaki temel fark şudur: static üyeler sınıfa ait tek bir kopya olarak bellekte tutulurken, instance üyeler her nesne için ayrı ayrı oluşturulur. Bu ayrımı anlamadan yazılan kod, özellikle main metodundan bir instance değişkene ya da metoda erişmeye çalışıldığında derleyicinin fırlattığı "non-static variable cannot be referenced from a static context" hatasıyla sonuçlanır. Bu hatayı gören neredeyse her Java öğrencisi aynı şaşkınlığı yaşar; sorun sende değil, kavramın kendisinde bir alışma süreci vardır.

Bu yazıda static ve instance değişkenin bellekte nasıl davrandığını, bir sınıfın tüm nesneleri arasında nasıl paylaşıldığını ve her nesnenin kendine özel verisini nasıl koruduğunu adım adım göreceksiniz. Amaç, ezberlemeden önce "neden böyle çalışıyor" sorusuna cevap bulmanız.

Static ve Instance Değişken Nedir? Temel Fark

Bir sınıf yazdığınızda aslında bir şablon tanımlarsınız; o şablondan new anahtar kelimesiyle ürettiğiniz her şey bir nesnedir. Static değişken bu şablonun kendisine, yani sınıfa aittir ve bellekte yalnızca bir kez var olur. Sınıftan kaç nesne üretirseniz üretin, static değişkenin tek bir kopyası vardır ve tüm nesneler bu kopyayı paylaşır. Instance değişken ise tam tersine, her nesne oluşturulduğunda o nesneye özel yeni bir kopya olarak heap belleğinde yaratılır.

Bunu günlük hayattan bir benzetmeyle düşünebilirsiniz: bir okulun "toplam öğrenci sayısı" tüm okul için geçerli tek bir bilgidir — bu static bir değere benzer. Ama her öğrencinin kendi "adı" ve "notu" o öğrenciye özeldir, başka bir öğrenciyle paylaşılmaz — bu da instance değişkene karşılık gelir. Sınıf, öğrencilerin ortak şablonuyken; her öğrenci, o şablondan üretilmiş ayrı bir nesnedir.

Bellek tarafında bakıldığında static değişkenler sınıfın kendisiyle ilişkili bir alanda tutulurken, instance değişkenler her nesnenin kendi heap alanında saklanır. Bu ayrım yalnızca teorik bir detay değildir; hangi değişkene nereden erişebileceğinizi, değerin ne zaman sıfırlanacağını ve verinin nesneler arasında paylaşılıp paylaşılmayacağını doğrudan belirler. Bu temel ayrımı sağlam kurmak, ileride nesne yönelimli programlamanın diğer konularını (kalıtım, çok biçimlilik, kapsülleme) anlamlandırmayı da kolaylaştırır. Konuyu uygulamalı örneklerle, geri bildirim alarak pekiştirmek isteyenler için birebir Java özel dersi bu tür temel kavramların üzerinde durarak ilerleyen bir yapı sunar.

Static Değişken Bellekte Nasıl Tutulur?

Static değişken, JVM tarafından sınıf yüklendiği anda bir kez ayrılan ve sınıfla ilişkilendirilen bir alanda tutulur. Bu alan, o sınıftan üretilen tüm nesneler tarafından ortaklaşa kullanılır; yani bir nesne static değişkenin değerini değiştirdiğinde, bu değişiklik aynı sınıftan üretilmiş diğer tüm nesneler için de geçerli olur. Bunun en somut örneği, oluşturulan nesne sayısını takip eden bir sayaçtır.

Aşağıdaki örnekte her yeni nesne oluşturulduğunda static bir sayaç bir artırılır ve bu sayaç tüm nesneler arasında paylaşılır:

public class Ogrenci {
    static int ogrenciSayisi = 0;
    String ad;

    public Ogrenci(String ad) {
        this.ad = ad;
        ogrenciSayisi++;
    }

    public static void main(String[] args) {
        Ogrenci o1 = new Ogrenci("Ayşe");
        Ogrenci o2 = new Ogrenci("Mehmet");
        Ogrenci o3 = new Ogrenci("Can");

        System.out.println("Toplam öğrenci: " + Ogrenci.ogrenciSayisi);
    }
}

Bu kodu çalıştırdığınızda ekranda "Toplam öğrenci: 3" yazdığını görürsünüz. Dikkat edilmesi gereken nokta şudur: ogrenciSayisi değişkeni o1, o2 veya o3 nesnelerinden herhangi birine değil, doğrudan Ogrenci sınıfına aittir. Üç nesne de aynı sayacı paylaşır ve her constructor çağrısında bu tek kopya güncellenir. Static değişkene Ogrenci.ogrenciSayisi şeklinde sınıf adı üzerinden erişilmesi de bu paylaşımlı yapının doğal bir sonucudur; nesne üzerinden erişmek çalışsa da, static bir değere sınıf adıyla erişmek kodun ne olduğunu daha net ifade eder.

Instance (Örnek) Değişken Her Nesne İçin Neden Ayrıdır?

Instance (Örnek) Değişken Her Nesne İçin Neden Ayrıdır?

Instance değişkenler, static değişkenlerin tam tersi bir mantıkla çalışır. Her new ifadesi çalıştığında JVM, o nesne için heap belleğinde ayrı bir alan açar ve sınıfta tanımlı instance değişkenlerin birer kopyasını bu alana yerleştirir. Yani iki farklı nesne aynı sınıftan üretilmiş olsa bile, instance değişkenlerinin değerleri birbirinden tamamen bağımsızdır.

Yukarıdaki Ogrenci sınıfındaki ad değişkeni tam olarak bu duruma örnektir. o1 nesnesinin ad değeri "Ayşe" iken, o2 nesnesinin ad değeri "Mehmet"tir; biri değiştiğinde diğeri hiçbir şekilde etkilenmez. Bunu doğrulamak için basit bir kontrol yeterlidir:

Ogrenci o1 = new Ogrenci("Ayşe");
Ogrenci o2 = new Ogrenci("Mehmet");

o1.ad = "Zeynep";

System.out.println(o1.ad); // Zeynep
System.out.println(o2.ad); // Mehmet

o1.ad değerini değiştirmek o2.ad değerini hiç etkilemez, çünkü ikisi belleğin farklı bölgelerinde duran, birbirinden habersiz kopyalardır. Bu davranış, instance değişkenlerin neden nesneye özgü "durum" (state) bilgisini tutmak için kullanıldığını da açıklar: bir bankacılık uygulamasında her hesabın bakiyesi, bir oyun karakterinin can puanı ya da bir öğrencinin notu gibi bilgiler instance değişken olarak tutulmalıdır, çünkü her biri kendi nesnesine özeldir ve başka bir nesneyle karışmamalıdır. Static ve instance ayrımının bu noktada netleşmesi, ilerleyen bölümlerde göreceğiniz "non-static variable" hatasının neden oluştuğunu anlamanın da temelini oluşturur.

Static Metot ile Instance Metot Çağırma Farkı

Java'da bir metodu çağırma şeklin, o metodun static mi yoksa instance mi olduğunu ele verir. Static bir metoda erişmek için nesne oluşturmana gerek yoktur; doğrudan ClassName.metot() yazarak çağırırsın. Instance metotlar ise sınıfın bir örneğine bağlı çalıştığı için önce new ile bir nesne üretip ardından nesne.metot() şeklinde çağrılmak zorundadır. Bu ayrım rastgele bir kural değil; metodun hangi veriye ihtiyaç duyduğuyla doğrudan ilişkilidir.

public class Hesaplayici {
    static int carpan = 2;
    int taban;

    Hesaplayici(int taban) {
        this.taban = taban;
    }

    static int ikiyleCarp(int sayi) {
        return sayi * carpan;
    }

    int tabanlaTopla(int sayi) {
        return sayi + this.taban;
    }
}

// Kullanım:
int sonuc1 = Hesaplayici.ikiyleCarp(5);      // nesne gerekmiyor
Hesaplayici h = new Hesaplayici(10);
int sonuc2 = h.tabanlaTopla(5);              // nesneye bağlı

Yukarıdaki örnekte ikiyleCarp metodu hiçbir nesne bilgisine ihtiyaç duymadan sabit bir işlem yapar, bu yüzden static tanımlanmıştır. tabanlaTopla ise her nesnenin kendine ait taban değerini kullandığı için instance olmak zorundadır. Bir metodu static mi instance mi yapacağına karar verirken kendine şunu sor: bu metot çalışmak için nesnenin kendi alanlarına (instance değişkenlerine) ihtiyaç duyuyor mu? Cevap evetse metot instance olmalıdır, çünkü static bir metot içinden instance değişkenlere doğrudan erişilemez. Cevap hayırsa ve metot yalnızca parametrelerle veya static verilerle çalışıyorsa static tanımlamak hem daha performanslı hem daha anlaşılır bir tercihtir.

Bu ayrımı çok sayıda örnek üzerinden pekiştirmek istersen Java bilgi seviyeni ölçen ücretsiz test ile hangi noktalarda static-instance kararını hâlâ karıştırdığını görebilirsin. Küçük projelerde bu ayrımı yanlış yapmak başta hata vermeyebilir ama sınıf büyüdükçe hangi verinin nesneye, hangisinin sınıfa ait olduğu netleşmezse kod karmaşıklaşır.

main Metodu Neden Static Olarak Tanımlanır?

main Metodu Neden Static Olarak Tanımlanır?

Bir Java programı çalıştığında JVM (Java Sanal Makinesi) senin sınıfından henüz hiçbir nesne oluşturmamıştır; ilk yapması gereken şey programın giriş noktasını bulup çalıştırmaktır. İşte tam bu noktada public static void main(String[] args) imzasındaki static anahtar kelimesi devreye girer. JVM, bir nesne üretmeden doğrudan sınıf üzerinden bu metodu çağırabilmek zorundadır; çünkü nesne oluşturmak için zaten çalıştırılabilir bir koda ihtiyaç vardır ve bu çelişkiyi çözen mekanizma static'liktir.

Eğer main metodu instance olarak tanımlansaydı, JVM'in onu çağırabilmesi için önce senin sınıfından bir nesne yaratması gerekirdi. Ama nesne yaratmak zaten bir kod çalıştırmayı, yani bir başlangıç noktasını gerektirir. Bu döngüsel bağımlılığı kırmanın yolu, main'i sınıfa ait, nesneden bağımsız bir üye olarak tanımlamaktır. Böylece JVM sınıfı yükler yükler yüklemez, hiçbir nesne oluşturma adımına gerek kalmadan doğrudan ClassName.main(args) mantığıyla programı başlatabilir.

Bu yüzden yeni başlayan öğrencilerin sık sorduğu "main içinde neden diğer metotları doğrudan çağıramıyorum" sorusunun cevabı da aynı mantığa dayanır. main statik bir bağlamda çalıştığı için, içinden yalnızca yine static olan üyelere doğrudan erişebilir. Instance bir metoda veya değişkene main içinden ulaşmak istiyorsan önce o sınıftan bir nesne oluşturman gerekir; aksi hâlde derleyici bunu bir hata olarak işaretler. Bu davranış Java'nın kaprisli olmasından değil, bellek ve nesne yaşam döngüsü mantığının doğal bir sonucundan kaynaklanır.

Özetle main metodunun static olması, programın "sıfır nesneyle" başlayabilmesinin garantisidir. Bu tasarım kararı sayesinde her Java uygulaması, ne kadar karmaşık olursa olsun, güvenilir ve öngörülebilir bir giriş noktasına sahip olur. Bu mantığı bir kez kavradığında, static ile ilgili çoğu derleme hatasının aslında aynı köke, yani "hangi üyenin nesneye hangi üyenin sınıfa ait olduğu" sorusuna dayandığını fark edeceksin.

Static ve Instance Üyelerin Karşılaştırılması

Şimdiye kadar anlatılan farkları tek bakışta görmek, kavramı zihninde netleştirmenin en pratik yoludur. Aşağıdaki tablo, static ve instance üyelerin dört temel özellik açısından nasıl ayrıştığını özetler.

Özellik Static Üye Instance Üye
Bellekte tutulduğu yer Sınıfa ait tek bir alanda, sınıf yüklendiğinde ayrılır Her nesne için heap üzerinde ayrı ayrı ayrılır
Kopya sayısı Tüm nesneler için tek bir kopya vardır Oluşturulan her nesne kendi kopyasına sahiptir
Çağırma şekli ClassName.üye şeklinde, nesneye gerek olmadan nesne.üye şeklinde, önce nesne oluşturularak
Tipik kullanım alanı Sayaçlar, sabitler, yardımcı hesaplama metotları Nesneye özgü durum bilgisi ve davranışlar

Tablodaki "kopya sayısı" satırı özellikle önemlidir çünkü static ve instance arasındaki neredeyse tüm pratik farklar buradan doğar. Bir static değişkeni değiştirdiğinde bu değişiklik o sınıftan üretilmiş tüm nesneler tarafından aynı anda görülür, çünkü ortada zaten tek bir değişken vardır. Instance değişkende ise her nesne kendi kopyası üzerinde çalıştığı için bir nesnedeki değişiklik diğerini etkilemez.

Çağırma şekli satırı da günlük kod yazarken en çok karşılaşacağın ayrımdır. Bir metodu ClassName.metot() biçiminde çağırabiliyorsan bu static bir üyedir; eğer önce new ile nesne oluşturup ardından o nesne üzerinden erişiyorsan instance bir üyeyle çalışıyorsun demektir. Bu tabloyu bir sonraki bölümde ele alınan derleme hatasını anlarken referans noktası olarak kullanabilirsin, çünkü hatanın kök nedeni tam olarak bu dört satırdaki ayrımın karıştırılmasından kaynaklanır.

'Non-Static Variable Cannot Be Referenced From a Static Context' Hatası Neden Oluşur?

Bu hata mesajını gördüğünde paniklemene gerek yok; neredeyse her Java öğrencisi bu satırla en az bir kez karşılaşır. Hatanın özü aslında çok basit bir çelişkiden kaynaklanır: static bir bağlamda, henüz var olmayan bir instance üyeye doğrudan ulaşmaya çalışıyorsun. Derleyici burada haklıdır, çünkü static bir metot (genellikle main) herhangi bir nesne oluşturulmadan çalışabilir; ama instance değişkenler ve instance metotlar yalnızca bir nesne yaratıldığında hafızada yer kaplar. Ortada nesne yoksa, o değişkenin de o an için "içi boş" demektir.

Bu durumu somut bir örnekle görelim. Aşağıdaki kod, bir sayacı tutan instance değişkene main içinden doğrudan erişmeye çalıştığı için derlenmez:

public class Sayac {
    int adet; // instance değişken

    public static void main(String[] args) {
        adet = 5; // HATA: non-static variable adet cannot be referenced from a static context
        System.out.println(adet);
    }
}

Derleyici burada şunu söylüyor: "adet değişkeni bir nesneye ait, ama sen bana hangi nesnenin adet'ini kastettiğini söylemedin." Çözüm, önce bir nesne yaratıp değişkene o nesne üzerinden ulaşmaktır:

public class Sayac {
    int adet; // instance değişken

    public static void main(String[] args) {
        Sayac s = new Sayac(); // önce nesne oluştur
        s.adet = 5;            // nesne üzerinden eriş
        System.out.println(s.adet);
    }
}

Bu tür hatalarla karşılaştığında kodun mantığını tek başına çözmeye çalışmak yerine geri bildirim almak öğrenme sürecini hızlandırır; birebir Java özel dersleri tam da bu noktada, hatanın neden oluştuğunu senin yazdığın koda bakarak canlı şekilde göstermeyi amaçlar. Unutma, bu hata senin mantığının yanlış olduğunu değil, sadece Java'nın static ve instance ayrımını net biçimde talep ettiğini gösterir.

Hatayı Adım Adım Çözme Rehberi

Bu hatayla karşılaştığında rastgele değişiklik yapmak yerine sistematik bir kontrol listesi izlemek, hem hatayı çözmeni hem de neden oluştuğunu kalıcı olarak kavramanı sağlar. Aşağıdaki adımları sırasıyla uygula:

  1. Derleyici mesajındaki satır numarasını ve hangi değişken veya metodun sorunlu olduğunu tam olarak belirle.
  2. O üyenin sınıf tanımında static anahtar kelimesiyle mi yoksa sadece tür ve isimle mi (instance) tanımlandığını kontrol et.
  3. Eğer üye instance ise, hatanın oluştuğu static metot (genellikle main) içinde ilgili sınıftan bir nesne oluştur.
  4. Üyeye artık doğrudan değil, oluşturduğun nesne referansı üzerinden eriş.
  5. Eğer o üye aslında tüm nesneler için ortak bir değer taşıması gerekiyorsa (örneğin oluşturulan toplam nesne sayısı gibi), instance yerine static yapmak daha doğru bir tasarım olabilir.
  6. Değişikliği yaptıktan sonra kodu yeniden derle ve aynı hatanın başka bir satırda tekrar edip etmediğini kontrol et.

Bu adımları uyguladıktan sonra hâlâ kafanın karıştığı noktalar olabilir; bu tamamen doğal, çünkü static/instance ayrımı Java'da nesne yönelimli düşünmenin ilk gerçek sınavlarından biridir. Benzer hata senaryolarını ve çözüm mantıklarını daha fazla örnekle pekiştirmek istersen Java öğrenme rehberleri arasında konuya özel içeriklere göz atabilirsin. Zamanla bu kontrol listesini elle takip etmene bile gerek kalmayacak; hatayı gördüğün an hangi üyenin static hangi üyenin instance olması gerektiğini otomatik olarak ayırt edeceksin.

Sık Sorulan Sorular

Static değişken ile instance değişken arasındaki temel fark nedir?

Static değişken sınıfa aittir ve tüm nesneler arasında paylaşılan tek bir kopyası bulunur; instance değişken ise her nesne için ayrı ayrı hafızada tutulur ve bir nesnenin değeri diğerini etkilemez.

Bir metot ne zaman static, ne zaman instance olarak tanımlanmalıdır?

Bir metot, çalışması için herhangi bir nesne durumuna (instance değişkenlere) ihtiyaç duymuyorsa static olarak tanımlanabilir; eğer metot nesneye özgü verilerle çalışıyorsa instance metot olması daha doğrudur.

'Non-static variable cannot be referenced from a static context' hatası tam olarak ne zaman ortaya çıkar?

Bu hata, static bir metot içinden (örneğin main içinden) bir instance değişkene veya instance metoda nesne oluşturmadan doğrudan erişmeye çalıştığında ortaya çıkar.

main metodu neden static olarak tanımlanır?

main metodu, Java Virtual Machine tarafından program başlarken henüz hiçbir nesne oluşturulmamışken çağrılır; bu yüzden nesneye ihtiyaç duymadan çalışabilmesi için static olarak tanımlanır.

Static bir değişkeni instance değişkene çevirmek ne zaman doğru olur?

Eğer bir değerin her nesne için farklı ve bağımsız olması gerekiyorsa, örneğin her nesnenin kendi ismi veya kendi durumu varsa, o değişkeni static yerine instance olarak tanımlamak doğru olur.

Bir sınıftaki tüm metotları static yapmak doğru bir yaklaşım mıdır?

Hayır; bu yaklaşım genellikle nesne yönelimli tasarımın avantajlarından uzaklaşmaya neden olur, çünkü nesnelerin kendi durumlarını taşıyabilmesi ve birbirinden bağımsız davranabilmesi instance yapıyla mümkün olur.

Static ve instance kavramları arasındaki bu ayrım, Java öğreniminde ilk karşılaşılan ama kalıcı olarak öğrenildiğinde çok şey açıklayan bir dönüm noktasıdır. Bu ayrımı sağlam bir zeminde pekiştirmek istersen Java yazılım kursu içeriğine göz atabilirsin.

Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 300'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara