Java’da Enum Türleri

Merhabalar, Java dilinde Enum türlerini detaylarıyla anlatan Türkçe bir kaynak bulamadığım için bu yazıyı yazmaya karar verdim, umarım bu alandaki eksiği bir nebze olsun kapatır.

Java’da Enum türleri önceden tanımlanmış sabit değerleri ifade etmek için kullanılır. Peki bununla neyi kastediyoruz? Mesela en klasik örnek haftanın günleri. Bir haftanın kaç gün olduğu ve hangi günlerden oluştuğu bilindiğine göre bunu aşağıdaki gibi bir Enum türüyle ifade edebiliriz.

public enum Gun {
    PAZARTESI,
    SALI,
    CARSAMBA,
    PERSEMBE,
    CUMA,
    CUMARTESI,
    PAZAR
}

Yukarıdaki kodu yazarak Gun adlı bir Enum türü tanımlamış olduk. İçerisindeki değerler sabit olduğu için tamamen büyük harf kullandık. Küçük harflerle enum sabitleri tanımlamak mümkündür ancak kod okunabilirliği açısından Java dilinde kabul görmüş bu yaklaşımı kullanmak daha iyi olacaktır.

Şimdi enumlar nasıl kullanılır ona bakalım:

Gun gun1 = Gun.PERSEMBE;    // doğru kullanım
Gun gun2 = Gun.PAZAR;       // doğru kullanım

Yukarıda gördüğünüz gibi Gun türündeki bir referansa atama yaparken sadece o türde tanımlanmış sabitleri kullanabiliyoruz. Böylece tür güvenliği (type safety) sağlamış oluyoruz. Enum sabitleri if/else veya switch içerisinde kullanılabilirler ve == operatörü ile karşılaştırılabilirler:

// örnek if kullanımı
public boolean haftasonuMu(Gun gun) {

    if(gun == Gun.CUMARTESI || gun == Gun.PAZAR) {
        return true;
    }

    return false;
}
// örnek switch kullanımı
public void gunYazdir(Gun gun) {

    switch (gun) {
        case PAZARTESI:
        System.out.println("Haftanin ilk gunu");
        break;

        case CUMA:
        System.out.println("Haftasonuna az kaldı..");
        break;

        case CUMARTESI: case PAZAR:
        System.out.println("Hafta sonu");
        break;

        default:
        System.out.println("Hafta ortasi");
        break;
    }
}

Bir enum türünün sahip olduğu bütün sabitleri görmek istersek Enum türlerine java derleyicisi tarafından otomatik olarak eklenen values() metodunu kullanabiliriz.

for (Gun gun : Gun.values()) {
    System.out.println(gun);
}

// Kodun çıktısı
PAZARTESI
SALI
CARSAMBA
PERSEMBE
CUMA
CUMARTESI
PAZAR

Diğer sınıflar gibi Enumların içerisinde de yapıcı metodlar, alanlar ve normal metodlar tanımlanabilir. Aşağıdaki kodu inceleyelim:

public enum Otomobil {

    MERCEDES(70),
    AUDI(80),
    FIAT(30),
    HONDA(48),
    TOYOTA(40);

    private int fiyat;

    private Otomobil(int f) {
        fiyat = f;
    }

    public int getFiyat() {
        return fiyat;
    }
}

11. satırda yukarıdaki Enum türü için, int türünde parametre alan bir yapıcı metot tanımlıyoruz. Yapıcı metodumuz parametre aldığı için Enum sabitlerini tanımlarken bu parametreyi geçmemiz gerekiyor, çünkü Enum sabitleri yaratılırken de nesne yaratılırken olduğu gibi yapıcı metot çağrılır.

Enumlar için yapıcı metot tanımlarken private erişim belirtecini kullanmak bir zorunluluktur. Eğer yapıcı metodu public ve protected yapmaya çalışırsanız derleme hatası alırsınız. Ancak hiçbir şey belirtmezseniz java derleyicisi otomatik olarak private erişim belirtecini ekleyecektir. Bu sebeple Enum türleri dışarıdan new operatörü ile yaratılamazlar. Enum türleri için yazılan yapıcı metotlar sadece enum sabitleri tarafından çağrılırlar. Yukarıdaki örnek için konuşacak olursak Otomobil türünün yapıcı metodu her bir sabit için birer kez olmak üzere toplamda 5 kere çağrılacak ve 5 tane enum sabiti yaratılacaktır. İlk örnekte verdiğimiz Gun enum türünde yapıcı metot tanımlamamıştık ama o durumda bile java derleyicisi otomatik olarak private bir yapıcı metot eklemektedir.

Bunun yanında Enum türleri içerisinde aynen sınıflarda olduğu gibi alanlar ve metotlar tanımlayabiliyoruz. Yukarıdaki Otomobil türü içerisinde fiyat isimli bir alan tanımladık ve bu alanın değerini geri döndüren bir de metodumuz var. Şimdi bunu nasıl kullanıyoruz onu görelim:

for(Otomobil otomobil : Otomobil.values()) {
    System.out.println(otomobil + " " + otomobil.getFiyat() + " bin TL");
}

// Kodun çıktısı
MERCEDES 70 bin TL
AUDI 80 bin TL
FIAT 30 bin TL
HONDA 48 bin TL
TOYOTA 40 bin TL

Daha önce kullandığımız values() metodunu kullanarak enum sabitlerini tek tek tarıyoruz ve her birisi için fiyat bilgisini yazdırıyoruz.

Bu kadar örnekten sonra Enumlar java derleyicisi tarafından nasıl ele alınıyor ona biraz bakalım. Java’da Enum türleri aslında java.lang.Enum sınıfından kalıtılmış özel sınıflardır. Enum sabitleri ise bu özel sınıflardan yaratılmış public static final nesnelerdir. Dolayısıyla Enum türleri esasında java derleyicisi tarafından sınıfa çevrilmekte ve bir takım yardımcı alanlar/metotlar eklenerek yazılımcı için çok yararlı bir formata dönüştürülmektedir. Şimdi bu nasıl oluyor ona bakalım.

Bir önceki örnekte verdiğimiz Otomobil enum türünün derleme sonrası kabaca aşağıdakine benzer bir sınıfa dönüştüğünü düşünebilirsiniz:

public final class Otomobil extends Enum<Otomobil>{

    public static final Otomobil MERCEDES = new Otomobil(70);
    public static final Otomobil AUDI = new Otomobil(80);
    public static final Otomobil FIAT = new Otomobil(30);
    public static final Otomobil HONDA = new Otomobil(48);
    public static final Otomobil TOYOTA = new Otomobil(40);

    private int fiyat;

    private Otomobil(int f) {
        fiyat = f;
    }

    public int getFiyat() {
        return fiyat;
    }

    ...
    ...
    // java derleyicisi enum türleri için farklı alanlar ve metotlar tanımlamaktadır, o kısımları atlıyoruz
}

Burada dikkat edilmesi gereken birkaç nokta var. Gördüğünüz gibi yapıcı metot private olduğu için sadece sınıfın içerisinde tanımlanan sabitler bu yapıcı metodu çağırarak sınıftan nesne yaratmaktadırlar. Bu durumda enum sabitlerini o enum türünden yaratılmış nesneler olarak görebilirsiniz. Enum sabitleri aynı zamanda public static ve final olarak yaratılırlar. Böylece Enum türünü kullanacak kişi Otomobil.HONDA şeklinde bir ifadeyle yaratılan enum sabitine erişebilir.

Enum sabitleri final olduğu için bir kere yaratıldıktan sonra değiştirilemezler, bu yüzden Otomobil.HONDA = Otomobil.AUDI; şeklinde bir atama derleme hatası ile sonuçlanacaktır. Otomobil sınıfı da aynı şekilde java derleyicisi tarafından final olarak yaratılır. Bu da demek oluyor ki enum türleri kalıtılamaz.

Başka bir önemli nokta Otomobil sınıfının kalıttığı java.lang.Enum sınıfı. Her Enum türü otomatik olarak bu sınıfı kalıtmaktadır ancak bu kodu derlemeye çalışırsanız hata alırsınız. Çünkü java.lang.Enum sadece java derleyicisi tarafından üretilen sınıflar tarafından kalıtılabilir, bizler kendi yazdığımız sınıflarda bu sınıfı kalıtamıyoruz. Yukarıda yazmamın sebebi java derleyicisinin nasıl bir kod üreteceğini kabaca göstermek içindi. Enum türleri kendiliğinden bir sınıfı kalıttığı için enum türünü tanımlarken başka bir sınıfı kalıtmamız mümkün değildir, ancak farklı arayüzleri uygulamak mümkündür.

Bunların dışında java derleyicisi enum türlerini sınıfa dönüştürürken values(), valueOf() gibi metotlar eklemekte ve java.lang.Enum sınıfından bir takım metotlar kalıtmaktadır. Bunların detaylarına girmek isteyenler bu linkten bakabilirler.

Yazıda anlattıklarımızı özetleyecek olursak:

  • Enumlarda tür güvenliği (type safety) mevcuttur. Yani bir enum referensına sadece o türden bir enum sabiti atayabilirsiniz.
  • Enumlar if/else ve switch içerisinde kullanılabilirler, == operatörü ile karşılaştırılabilirler
  • Derleyici tarafından eklenen values() metodunu kullanarak bir Enum türü içerisindeki bütün sabitleri alabiliriz.
  • new operatörü kullanılarak nesneleri yaratılamaz. Yapıcı metotları private olmak zorundadır.
  • İçerisinde yapıcı metotlar, alanlar ve yardımcı metotlar tanımlanabilir.
  • java.lang.Enum sınıfını otomatik olarak kalıttıkları için başka sınıfı kalıtamazlar. Ancak başka arayüzleri uygulayabilirler.
  • Enum sabitleri otomatik olarak static ve final tanımlanırlar, yaratıldıktan sonra değiştirilemezler.
  • Enum türleri bir sınıfın içinde veya dışında yaratılabilirler.

Umarım faydalı olmuştur, kolay gelsin.

Share

2 Replies to “Java’da Enum Türleri”

  1. Paylaşımlarınız, anlatımınız çok açıklayıcı, çok anlaşılır. Daha fazla paylaşımda bulunmanızı rica ederim. Emeğinize sağlık…

Bir Cevap Yazın