Javada static anahtar kelimesinin kullanımı

Dünyada en çok kullanılan programlama dillerinden birisi olan Java'da static anahtar kelimesinin önemi tartışılmayacak seviyededir. Birçok yazılımcının kafasını karıştıran bu değişkenin ne amaçla ve nerelerde kullanılacağı hakkında bazı örneklerle bilgiler sunacağız. Static anahtar kelimesi hem Java sınıflarında hem metodlarda hemde değişkenlerde kullanılabilmektedir. Makalemizde aşağıda bulunan maddeler sırasıyla anlatılacaktır:
  1. Sınıf seviyesinde static kullanımı
  2. Metod seviyesinde static kullanımı
  3. Import edilen kütüphane seviyesinde static kullanımı
  4. Static kullanımlar ne zaman gerçekleştirilmeli?
1. Sınıf seviyesinde static kullanımı:
Java'da sınıflar içerisinde bulunan değişkenler, oluşturulan her nesne için farklı alanda  tekrar tekrar oluşturulmaktadır. Örneğin ürün adı, markası, modeli ve ücreti gibi 4 farklı değişkeni bulunan bir sınıfta, bu sınıfla alakalı oluşturulan her nesne  için bellekte farklı alanlarda ürün adı, markası, modeli ve ücreti bilgileri tutulmaktadır. Bu nesnelere atanan değerler tamamen birbirinden bağımsızdır. Bundan dolayı bu değişkenler nesne değişkeni olarak tanımlanmaktadır. Ancak bazı uygulamalarmızda sınıflarda kullanılan değişkenlerin ortak bir yerden veri çekmesini sağlamamız gerekmektedir. Örneğin ürünlerin girildiği bir sınıfta toplam ürün miktarının bu sınıfa ait bir değişken ile sayılması istenildiğinde static anahtar kelimesinden yararlanmamız gerekmektedir. static anahtar değişkeni daha sınıfla alakalı herhangi bir nesne oluşturulmadan bellekte bir alan kaplamaktadır. Sınıftaki değişkeni ortak bir alana yazma yapmasından dolayı bu değişkenler sınıf değişkeni olarak ifadelendirilmektedir. Yani yazılımcı istediği kadar bu sınıfa bağlı nesne oluştursun. static olarak ifadelendirilen değişkenler sadece bir kere bellekte oluşturulmaktadır ve her oluşturulan nesne bu değişkene ait ortak belleği kullanmaktadır. Aşağıda oluşturulan örnekte bu durumu daha açıklayıcı şekilde ifadelendirelim:
package com.yazilimdersi.info.statickullanimi; 

public class Urun{ 

    private String urunadi;
    private String marka;
    private String model;
    private int fiyat;
    
    #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
    public static int urunsayisi = 0;

    public Urun(String urunadi, String marka, String model, int fiyat) { 
        this.urunadi= urunadi; 
        this.marka = marka; 
        this.model = model;
        this.fiyat = fiyat;

        #Urun sınıfına ait her nesne oluşturulduğunda urunsayisini bir artıralım. 
        urunsayisi++; 
    } 
}
Yukarıda bulunan sınıfta 4 adet nesne değişkeni ve 1 adet sınıf değişkeni bulunmaktadır. urunadi, marka,model ve fiyat değişkenleri nesne, urunsayisi değişkeni ise sınıf değişkeni olarak belirlenmiştir. Şimdi aşağıda bulunan StaticOrnekProgram sınıfı içerisinde Urun sınıfına ait nesneler oluşturalım ve urunsayisinin sonuclarını ekrana basalım.
package com.yazilimdersi.info.statickullanimi; 

public class StaticOrnekProgram { 
     
    public static void main(String args[]) { 

        System.out.println("ürün sayısı: " + Urun.urunsayisi); 

        #üc tane urun nesnesi olusturalım. 
        Urun urun1 = new Urun("Pals Oximeter", "Erne", "UT 100", 1200); 
        Urun urun2 = new Urun("Ateşölçer", "Thermoflash", "LX-26", 1000); 
        Urun urun3 = new Urun("FLOWMETRE", "Özen", "Perfect Aneroid", 240); 

        int urunsayisi = Urun.urunsayisi;
        System.out.println("Nesnelerden sonra ürün sayısı: " + urunsayisi); 

        urunsayisi1 = urun1.urunsayisi; 
        System.out.println("İlk nesnede ürün sayısı: " + urunsayisi1); 

        urunsayisi2 = urun2.urunsayisi; 
        System.out.println("İkinci nesnede ürün sayısı: " + urunsayisi2); 

        urunsayisi3 = urun3.urunsayisi; 
        System.out.println("Üçüncü nesnede ürün sayısı: " + urunsayisi3);
 
    } 
}
StaticOrnekProgram sınıfı çalıştırıldığında oluşacak olan ekran çıktıları şu şekilde olacaktır:
ürün sayısı: 0 
Nesnelerden sonra ürün sayısı: 3 
İlk nesnede ürün sayısı: 3 
İkinci nesnede ürün sayısı: 3
Üçüncü nesnede ürün sayısı: 3
Ekran çıktısında gördüğünüz üzere nesneler oluşturulduktan sonra setlenen ürün sayısı bilgisi static değişkene bağlı olduğundan her zaman aynı sonucu dönmektedir. Farklı nesneler içinde her zaman 3 rakamını dönmüştür. Ayrıca kodlamada da gördüğünüz üzere bu değişkenlere sınıflar aracılığıyla erişelebilindiği gibi, nesneler aracılığıyla da erişilebilmektedir. Dikkat ederseniz yapıcı(constructor) metodu içerisinde yapılan urunsayisina ait +1 artırımı her oluşturulan nesne ile birlikte gerçekleştirilmektedir. Daha önceden belirtiğim gibi bu değişkenler program başlatıldığında bellekte oluşturulmaktadır ve erişimler hep aynı bellek alanındaki değere gerçekleştirilmektedir.

2. Method seviyesinde static kullanımı:
Java'da sınıflar içerisinde bulunan methodlarda static anahtar kelimesi kullanılarak oluşturulabilmektedir. Normalde herhangi bir sınıfa bağlı metoda erişmek istiyorsanız, öncelikle bu sınıfa bağlı nesneyi oluşturmanız gerekmektedir. Ancak static tanımlı olan methodlarda nesne oluşumuna ihtiyaç duyulmaksızın erişim gerçekleştirilmektedir. Örneğin yukarıda oluşturduğumuz Urun sınıfındaki urunsayisi değişkenine bir metod ile erişmek istersek, bunu aşağıdaki kodlama ile gerçekleştirebiliriz:
package com.yazilimdersi.info.statickullanimi; 

public class Urun{ 

    private String urunadi;
    private String marka;
    private String model;
    private int fiyat;
    
    #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
    public static int urunsayisi = 0;

    public Urun(String urunadi, String marka, String model, int fiyat) { 
        this.urunadi= urunadi; 
        this.marka = marka; 
        this.model = model;
        this.fiyat = fiyat;

        #Urun sınıfına ait her nesne oluşturulduğunda urunsayisini bir artıralım. 
        urunsayisi++; 
    }

    public static int urunsayisiGetir() {
        return urunsayisi;
    } 

}
Yukarıda bulunan kodlamada urunsayisiGetir() metodu ile normalde Urun.urunsayisi şeklindeki yaptığımız erişimin yerine bu metodu kullanabiliriz. Yapılan çağrı sonucunda dönecek değer aynıdır ancak değişkenlere direkt değilde, methodlar üzerinden erişim daha anlaşılır kabul edilmektedir. Örnek verecek olursak yukarıda kullandığımız StaticOrnekProgramı şu şekilde yazabiliriz artık:
package com.yazilimdersi.info.statickullanimi; 

public class StaticOrnekProgram { 
     
    public static void main(String args[]) { 

        System.out.println("ürün sayısı: " + Urun.urunsayisi); 

        #üc tane urun nesnesi olusturalım. 
        Urun urun1 = new Urun("Pals Oximeter", "Erne", "UT 100", 1200); 
        Urun urun2 = new Urun("Ateşölçer", "Thermoflash", "LX-26", 1000); 
        Urun urun3 = new Urun("FLOWMETRE", "Özen", "Perfect Aneroid", 240); 

        int urunsayisi = Urun.urunsayisiGetir();
        System.out.println("Nesnelerden sonra ürün sayısı: " + urunsayisi); 
 
    } 
}
Method üzerinden yapılan çağrıda oluşacak çıktı aynı olacaktır :
ürün sayısı: 0 
Nesnelerden sonra ürün sayısı: 3 
Daha öncede belirtiğimiz gibi direkt Urun sınıfına ait urunsayisi değişkenine erişebiliyoruz herhangi bir nesne tanımlanmadan. Ancak kod okunurluğu açısından pek tavsiye edilmediğinden bu işlemi metodlar üzerinden gerçekleştiriyoruz. 

Burada en önemli üzerinde durulması gereken nokta, static metodu içerisinde sadece static değişkenlerine erişim bulunmaktadır. Yani urunsayisi yerine urunadi değişkenini bu metod içerisine yazsaydım uygulama hata verecekti. Static methodlar içerisindeki değişkenler nesne değişkeni olamazlar. Onlar da static anahtar kelimesini kullanan değişkenler olmak zırundadır. Aynı şekilde static method içerisinde nesne metodu çağrılamaz. Bunun açıklamasını şu şekilde gerçekleştirebiliriz: Static metod ve değişken dışındaki nesne değişkenleri program çalıştığı esnada yapılan çağrılarla oluşturulduğundan bunlar sonradan bellekte yer kaplamaktadır. Halbuki static değişkene sahip metodlar daha program çalıştırılır çalıştırılmaz direkt olarak bellekte yer oluşturduğundan metod içerisindeki değişkenlerinde de daha önceden bellekte yer alması gerekmektedir. Bu nedenle bunlarında static olarak tanımlanmış sınıf değişkenleri olması zorunludur.
 
3. Import edilen kütüphane seviyesinde static kullanımı:
Static methodların sınıf adı ile çağrıldığını üstteki maddede detaylı olarak açıkladık. Örnek verecek olursak javada math clasını direkt olarak static biçimde kodumuza import edebilmekteyiz. Bunun sebebi Math classın içerisinde bulunan tüm metodların static olarak tanımlanmasındadır. Math sınıfı içerisinde bulunan metodlara Math.cagrilacakMetodAdi() fonksiyonu ile erişebiliriz. Ayrıca kodumuza direkt olarak Math sınıfını static import olarak ekleyerek Math sınıfını yazmamıza gerek kalmadan direkt metod ismi ile erişim sağlayabiliriz. Aşağıdaki kodlamada Math sınıfı kodumuza static olarak import edilmiştir:
package com.yazilimdersi.info.statickullanimi; 

import static java.lang.Math.*; 

public class OrnekProgram { 

    public static void main(String args[]) { 
    
        System.out.println("Cosinus 90: " + cos(90)); 
        System.out.println("Pi sayısı: " + PI); 
    } 
}
Yukarıda bulunan kodlamada Math.cos() metodu yerine direkt cos() şeklinde bir çağrım gerçekleştirdik. Bunun sebebi de import static olarak kodumuza eklediğimiz java.lang.Math sınıfıdır.

4. Static kullanımlar ne zaman gerçekleştirilmeli?
Static anahtar kelimesine bağlı değişkenler ortak bellekten okuma yapmak istediğimiz durumlarda kullanılmalıdır. Örnekte belirtiğimiz üzere ürünlerin tutulduğu bir programda oluşturulan her ürünle alakalı farklı nesneler kullanılmalıdır. Çünkü her nesneye bağlı ürün adı, markası, model ve fiyatı farklı olabilir ancak depoda bulunan toplam ürün sayısı aynıdır. Toplam ürün sayısını aynı sınıf içerisinde bulunan bir değişken ile tutmak istiyorsak, static metodunu kullanmamız yeterli olacaktır. Böylelikle bu değişkene her erişimde farklı nesneler tanımlanmış olsa bile ortak bellek havuzundan veri okuduğu için değerler her zaman aynı olacaktır. 
comments powered by Disqus