C / C++ gibi başka programlama dillerinde de bulunan Enumeration Java’ya 1.5 sürümünde kazandırılmıştır. Enum, enumeration(numaralandırma) olarak da adlandırılır, alanları sabit bir sabitler kümesinden oluşan java.lang.Enum dan türeyen özel sınıf türüdür. Enum’un amacı derleme zamanında(compile time) tip güvenliğini(type safety) sağlamaktır.
Örneğin, haftanın günlerinin basit enum’u yapalım.
1 2 3 4 5 6 7 8 9 |
public enum EnumGun { PAZARTESI, SALI, CARSAMBA, PERSEMBE, CUMA, CUMARTESI, PAZAR } |
Enum’ların Yapısı
EnumGun diye oluşturduğumuz enum derlendikten sonra aslında şu şekilde olacaktır :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public static final class EnumGun extends Enum { private EnumGun(String s, int i){ super(s, i); } public static EnumGun[] values(){ return (EnumGun[]) values.clone(); } public static EnumGun valueOf(String s){ return (EnumGun)Enum.valueOf(EnumGun, s); } public static final EnumGun PAZARTESI; public static final EnumGun SALI; public static final EnumGun CARSAMBA; public static final EnumGun PERSEMBE; public static final EnumGun CUMA; public static final EnumGun CUMARTESI; public static final EnumGun PAZAR; private static final EnumGun[] values; static { PAZARTESI = new EnumGun("PAZARTESI", 0); SALI = new EnumGun("SALI", 1); CARSAMBA = new EnumGun("CARSAMBA", 2); PERSEMBE = new EnumGun("PERSEMBE", 3); CUMA = new EnumGun("CUMA", 4); CUMARTESI = new EnumGun("CUMARTESI", 5); PAZAR = new EnumGun("PAZAR", 6); values = (new EnumGun[] { PAZARTESI, SALI, CARSAMBA, PERSEMBE, CUMA, CUMARTESI, PAZAR }); } } |
Özel tip olan enum’un aslında Singleton sınıftan farkı olmadığını gördünüz. Kod içerisinde önemli olan yerleri koyu renkle işaretledim. Bu işaretlediklerimden yola çıkarak ;
- Tüm enumlar gizlice java.lang.Enum sınıfından türer. Java’da bir sınıfın yalnızca bir ebeveyni olabildiğinden, bir enum başka birşeyden türeyemez.
- Enum’lar herhangi bir sınıfın üst sınıfı olamaz.
- new anahtar kelimesi ile Enum nesneleri oluşturulamaz.
- Enum’lar yapılandırıcılara, bloklara ve statik bloklara, değişkenlere ve metotlara sahip olabilir.
- Enum’lar interface’leri implement edebilir.
Enumdaki sabitlerimize başka değerlerde verebiliriz. Bunun için yapılandırıcıyı(constructor) değiştirmek yeterlidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public enum EnumGun { PAZARTESI("PZT"), SALI("SAL"), CARSAMBA("CAR"), PERSEMBE("PER"), CUMA("CUM"), CUMARTESI("CMT"), PAZAR("PZR"); private String kisaltma; EnumGun(String kisaltma){ this.kisaltma = kisaltma; } public String getKisaltma() { return kisaltma; } } |
Tüm enum’lar java.lang.Enum soyut sınıfından türediğini söylemiştik. Bu sayede üst sınıftan bir takım özellikleri almaktadır. name(), ordinal(), valueOf() bunların yanında Comparable ve Serializable özelliklerinide barındırmaktadır.
Örnek ile açıklayalım.
1 2 3 4 5 6 7 |
EnumGun gunPzt = EnumGun.PAZARTESI; System.out.println(gunPzt.ordinal()); // Dizideki indeksini verir. System.out.println(gunPzt.name()); // Sabit'in adını döndürür. EnumGun[] values = EnumGun.values(); // Tüm sabitlerini döndürür. EnumGun gun = EnumGun.valueOf("PAZARTESI"); // String'i enum'a dönüştürür. |
Enum Koleksiyonları(Collections) – EnumSet ve EnumMap
Java 1.5 ile beraber java.util paketine enumları destekleyen iki tane koleksiyon geldi. Bunlar EnumSet ve EnumMap
EnumSet
1 |
Set enumSet = EnumSet.of(EnumGun.CUMARTESI, EnumGun.PAZAR); |
EnumMap
1 2 3 |
Map enumMap = new EnumMap(EnumGun.class); enumMap.put(EnumGun.CUMARTESI, EnumGun.CUMARTESI.getKisaltma()); enumMap.put(EnumGun.PAZAR, EnumGun.PAZAR.getKisaltma()); |
Sonuç olarak …
1 2 |
private static final int BASARILI = 1; private static final int BASARISIZ = 0; |
İçinde bulunduğum projelerde enumlar yerine bir dizi önceden tanımlanmış değeri temsil eden çok sayıda sabit görüyorum. Bunu, enumlara aşina olmayan deneyimsiz programcılara atfediyorum.
Database’de verilere baktığımızda 1, 0 gibi sayılar görüyoruz ve ne anlama geldiklerini koddan araştırıp buluyoruz. Enumlar bu “sihirli numaraları” kaldırır. Bunlar, gerçekten kendi başına bir şey ifade etmeyen sayılardır. Bu sayıları gerçek değerlerle değiştirirseniz, kodunuz daha anlamlı olur.
Ayrıca, enumlar, yanlış değerlerin bir işleve iletilmesini engeller. Yöntemin girdi olarak aldığı değerleri kısıtlamak istiyorsanız, ideal olarak enumları kullanmalısınız. Varsayalım ki, bit metot yazdınız ve bunu diğer yazılımcı arkadaşlarınızla paylaşacaksınız. Bu metodunuz parametre olarak haftanın gününü alacaktır ve içeride bir takım gün kontrolleri yapıp ekrana birşeyler yapacaktır. Bu parametreyi String olarak belirlerseniz bu metodu kullanacak kişi nasıl kullanacağı konusunda endişeye düşecektir. O metoda parametre geçerken İngilizce olarak mı günleri göndermeliyim, Türkçe olarak mı göndermeliyim yoksa kısaltma olarak mı göndermeliyim diye düşünüp duracaktır ve sonrasında yazdığınız metoda bakmak zorunda kalacaktır. Eğer yukarıdaki enum’u metodumuza parametre olarak istiyor olsaydık kullanacak kişi korkusuzca metodunuzu çağırabilecekti.
Çok güzel olmuş
Süper bir anlatım olmuş, samimi olarak söylüyorum teşekkür ederim. Bu bana çok yardımcı oldu.