29 Ekim 2020

Java Enum Kullanımı

ile gökhan

Haftanın günleri , yılın ayları vb. gibi sonlu değer kümesine sahipsek Java’da enum kullanımı yaygındır. Enumlar sabit bir değerler kümesi gibidir. Enum içerisinde tanımlanmış değerler bir sınıf, interface olabileceği gibi bir inner classda olabilir.

Enum kullanmak , kodumuzun içersinde bir grup constant değişken kullanmaktan daha faydalıdır. Çünkü enumlar type-safe checking (tip güvenliği kontrolü) sağlamaktadır. Sayısal ve ya String değişkenler ile geçersiz bir değer iletilebilir ve run-time anına kadar öğrenemeyiz. Enum ile bir derleyici hatası vermeden geçersiz bir enum değeri oluşturmak imkansızdır.

public enum Gezegenler {
    MARS,JUPITER,NEPTUN,SATURN
}

Enum değerler sabitler olarak kabul edildiği için genellikle snake_case olarak adlandırılan bir formatta yazılırlar. Bu formatta enum değerler büyük harfle yazılırlar, Enum değer birden fazla kelimeden oluşuyorsa _ ile ayrılırlar. (Örn: KAR_YAGISI, YAGMUR_YAGISI gibi).

Enumlarda tanımlanan sabitler, static ve final değerler gibi davranırlar. Bu yüzden enumlar ile equals() ya da == gibi işlemler yapabilirsiniz. Çünkü her bir enum değeri Java Sanal Makinesi (JVM) üzerinde yalnızca bir kez başlatılırlar.

Enumdaki değerleri bir diziye atmak için “values()” metodunu barındırır. Genellikle döngü işlemlerinde kullanılmaktadır. Aşağıdaki kodda görüldüğü gibi “name()” metoduyla enum değerini, “ordinal()” metoduyla index değerini öğrenebiliriz.

 for(Gezegenler g : Gezegenler.values()){         
           System.out.println(g.name()+" "+g.ordinal());
       }
/*   çıktısı aşağıdaki gibidir.
MARS 0
JUPITER 1
NEPTUN 2
SATURN 3
*/

Enumlar bir java sınıfı gibi ayrı bir tür olduğundan int vb. bir tür ile karşılaştıramazsınız. Örneğin aşağıdaki gibi bir kod derlenmeyecektir.

 if(Gezegenler.MARS == 2){ } // Derlenmeyecektir.

Enumlara ait diğer kullanışlı metod ise valueOf() metodudur. Bu metod ile enumdaki istediğimiz bir sabitin değerini elde edebiliriz. Bu metod kullanılırken enum sabitiyle String değer birebir aynı olmalıdır.

Gezegenler g = Gezegenler.valueOf("MARS"); //MARS
Gezegenler k = Gezegenler.valueOf("Mars"); // Exception Fırlatır.  IllegalArgumentException

Enumlarda extend ifadesini kullanarak ilgili enumu genişletemezsiniz.

public enum Uzay extend Gezegenler{   // DERLENMEZ!!!.  
}

Enumlarda switch-case yapısını kullanabilirsiniz. Aşağıdaki örnekte kullanımı gösterilmiştir.

       Gezegenler g =  Gezegenler.JUPITER;
        switch(g){
            case MARS:
                System.out.println("Mars");
                break;
            case JUPITER:
                  System.err.println("Jüpiter");
                break;
            default:
                System.out.println("Başka bir gezegen");
                break;
        }

Enumlarda constructor, method, değişken tanımı yapılabilir. Aşağıdaki örnekte bu durum örneklendirilmiştir. Ancak instance variable olan değişkenimizi final olarak işaretlemek düzgün bir kod bloğu için gereklidir. Çünkü enum değerlerimizin değişmesini istemeyiz.

public enum Gezegenler {
    MARS("Kırmızı"), DUNYA("Mavi"), JUPITER("Turuncu");
    private final String renk;
    private Gezegenler(String renk){
        this.renk = renk;
    }
    public void printRenk(){
        System.out.println(renk);
    }
}

Tüm enum constructorlar private’dir. (Kod bloğunda belirtilmese bile.) Çünkü enumları genişletemezsiniz ve constructor yalnızca enum sınıfı içerisinden çağrılabilir. Bir enum sınıfındaki constructor public ve ya protected yazılırsa kod bloğu derlenmeyecektir.

Herhangi bir sınıftan enum sınıfımızdaki enum değerini çağırdığımızda, Java tüm enum değerleri oluşturur. Bundan sonraki her enum çağırımda constuctor daha önce çağrıldığı için önceki oluşturulmuş enum değerini yazar. Aşağıdaki kod bloğunda bu örneklendirilmiştir. Örnekte de görüldüğü gibi Örnek isimli enum classımızdan yapılan ikinci çağrıda herhangi bir şey yazmadı.

public enum Ornek {
    ORNEK(true);
    private Ornek(boolean b) {
        System.out.println("constructor");
    }
}
public class PrintOrnek {
    public static void main(String[] args) {
        System.out.println("başlangıç, ");
        Ornek ilkCagri = Ornek.ORNEK;  //Constructor Yazar
        Ornek ikinciCagri = Ornek.ORNEK; //YAZMAZ !!!!
        System.out.println("bitiş");
    }
}