İçeriğe geç

Enum — Sabit Bir Seçenek Listesi

Başlangıç 8 dk Çok sık karşılaşılır

Önce şunu oku: final ve static — Kilitli Olan ve Ortak Olan

30 saniyede özet

enum, bir değerin alabileceği seçenekleri baştan sayar: yazım hatası derlenmez, switch eksik seçeneği yakalar. Enum aslında bir sınıftır; alan ve metot taşıyabilir. Veritabanına sırasını değil adını yazarsın.

Bir restoranın menüsünde üç yemek var. Garson “pizzza” yazarsa mutfak ne yapacağını bilemez; menüde öyle bir şey yok.

Kodda da bazı değerlerin yalnızca birkaç seçeneği vardır. Onları serbest metin yerine sabit bir menü olarak yazmanın yolu enum’dur.

Metinle her yazılış içeri girer; enum'da yalnızca listedeki seçenekler vardır.
Adım adım oku
  1. Durum String olarak tutulunca KARGODA, kargoda ve KARGODAA hepsi kabul ediliyor.
  2. enum Durum yalnızca üç seçenek tanımlıyor: HAZIRLANIYOR, KARGODA, TESLIM_EDILDI.
  3. Durum.KARGODAA yazmak derleme hatası verir; yazım hatası programa hiç giremez.
  4. Sabit bir menü: sürpriz yok.
  1. Bayt: Kargodaki siparişleri listeledim, yarısı eksik çıktı!

  2. Sen: Durumlar nasıl yazılmış?

  3. Bayt: Kimisi KARGODA, kimisi kargoda, biri de KARGODAA. Hepsi metin.

  4. Bayt: O zaman seçenekleri bir menüye yazalım. Menüde olmayan yazılamasın.

Metin yerine sabit bir liste

Bir enumBir değerin alabileceği seçenekleri baştan sayan tip. Listede olmayan bir değer derlenmez.Enum bir sınıftır: her sabit onun tek bir nesnesidir ve alan, kurucu, metot taşıyabilir. Sabitler tekil olduğu için == ile karşılaştırılabilir.Sözlükte gör → bir değerin alabileceği bütün seçenekleri baştan sayar. Listede olmayan bir değeri yazamazsın; derleyici durdurur.

Sabit bir menü
enum Durum { HAZIRLANIYOR, KARGODA, TESLIM_EDILDI }
Durum d = Durum.KARGODA; // listeden seçildi
Durum e = Durum.KARGODAA; // derleme hatası: böyle bir seçenek yok

Switch ifadesi enum’daki her seçeneği ele almak zorundadır. Enum’a yeni bir durum eklediğinde, onu unuttuğun her switch derlenmez.

Eksik seçenek derlenmez
String etiket = switch (d) {
case HAZIRLANIYOR -> "Hazırlanıyor";
case KARGODA -> "Yolda";
case TESLIM_EDILDI -> "Teslim edildi";
};
Kafam karıştı, daha basit anlat

enum bir açılır listedir. Listede ne varsa o seçilebilir, fazlası değil. Yeni bir seçenek eklersen Java seni onu kullanmadığın yerlere kadar götürür.

Hızlı kontrolBaşlangıç

Sipariş durumunu String yerine enum olarak tutmanın en önemli faydası nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Enum aslında bir sınıf

Her enum sabiti, o enum sınıfının tek bir nesnesidir. Bu yüzden alanlar, bir kurucu ve metotlar taşıyabilir.

Her seçenek kendi bilgisini taşır
enum TransferTipi {
FAST(new BigDecimal("0.00")),
EFT(new BigDecimal("4.50")),
SWIFT(new BigDecimal("25.00"));
private final BigDecimal ucret;
TransferTipi(BigDecimal ucret) {
this.ucret = ucret;
}
BigDecimal ucret() {
return ucret;
}
}

Böylece “tip EFT ise ücret şu” diye uzayan if-else zincirleri kaybolur: bilgi, ait olduğu seçeneğin içinde durur. Her sabit tek bir nesne olduğu için enum’ları == ile karşılaştırmak da güvenlidir.

Kafam karıştı, daha basit anlat

Her enum seçeneği küçük bir kartvizit gibidir: adının yanında kendi bilgisini de taşır. Ücreti sormak için tabloya bakmazsın, doğrudan kartvizite bakarsın.

Hızlı kontrolBaşlangıç

İki enum değerini karşılaştırmak için `==` kullanmak güvenli midir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Bu ücret hesabına yeni bir transfer tipi (KRIPTO) eklendi. Kod derlendi ama KRIPTO transferleri ücretsiz geçiyor. Sorunun kaynağı hangi satır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Hatalı satıra dokun, sonra kontrol et.

Ucret.java
Java 21UTF-8LF

Satır satır: metinden enum’a

Dışarıdan gelen bir metni (bir istek parametresi, bir dosya satırı) enum’a çevirmen gerekebilir.

`Durum.valueOf("kargoda")` çağrılınca ne olur? Cevabı göster

IllegalArgumentException. valueOf adı birebir, büyük-küçük harfiyle arar. “kargoda” diye bir sabit yok; “KARGODA” var.

Dışarıdan gelen metni güvenle çevirmek

DurumOkuyucu.java
1String girdi = "kargoda";
şu an çalışan satırDurum d1 = Durum.valueOf(girdi);
3Durum d2 = Durum.valueOf(girdi.toUpperCase(Locale.ROOT));
4String ad = d2.name();
5int sira = d2.ordinal();

Debug

Adım 1/4

valueOf Ad birebir aranır. "kargoda" bulunamaz ve IllegalArgumentException fırlatılır.

d1
= hata
Java 21UTF-8LF2:1

Sol/sağ ok tuşlarıyla da gezebilirsin.

Dışarıdan gelen durum metni

Tohum 677418

enum Durum { HAZIRLANIYOR, KARGODA, TESLIM_EDILDI }

    Oynat ya da adımla: her adımda bir girdi okunur.

    Hız
    Adım 0

    Şu an ne oldu?

    String olarak sakla

    Dört gerçek durum yazımı ve bir yazım hatası gelecek.

    Görevler0/3

    • Yazım hatasını sessizce kaydetaçık

      İpucu

      Varsayılan ayarlar yeter.

    • Türkçe "i" yüzünden geçerli bir durumu reddetaçık

      İpucu

      Büyütmeyi makinenin diline bırak.

    • Bütün geçerli yazımları tanı, yazım hatasını reddetaçık

      İpucu

      Dilden bağımsız büyüt.

    Olay günlüğü (0)

    Henüz olay yok. Oynat veya adımla.

    1. Varsayılanla oynat. Metin olarak saklayınca yazım hatası KARGODAA da bir durum gibi kaydedildi.
    2. “Durum.valueOf(girdi)” seç. Küçük harfle gelen her geçerli durum reddedildi.
    3. “Türkçe JVM” seçeneğini dene. teslim_edildi, TESLİM_EDİLDİ’ye döndü ve reddedildi.
    4. “Locale.ROOT” seç. Dört geçerli yazım tanındı, yazım hatası reddedildi.
    Hızlı kontrolBaşlangıç

    Program ne yazdırır?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
    Oku.java
    1enum Durum { HAZIRLANIYOR, KARGODA, TESLIM_EDILDI }
    2
    3Durum d = Durum.valueOf("TESLIM_EDILDI");
    4System.out.println(d.name() + " " + d.ordinal());
    Java 21UTF-8LF

    EnumMap ve EnumSet

    Anahtarı enum olan bir map ya da enum’lardan oluşan bir küme gerekiyorsa, bunlar için yapılmış iki hazır yapı var.

    Enum'a özel koleksiyonlar
    Map<Durum, Integer> sayac = new EnumMap<>(Durum.class);
    Set<Durum> acik = EnumSet.of(Durum.HAZIRLANIYOR, Durum.KARGODA);

    İkisi de enum’ların sayısının sabit ve küçük olduğunu bilir; içeride basit bir dizi gibi çalışır. Sıraları da enum’daki tanım sırasıdır, bu yüzden çıktıları hep aynı düzende gelir.

    Kafam karıştı, daha basit anlat

    Seçenekler sabit ve az olduğunda, her birine ayrılmış numaralı bir çekmece yeter. EnumMap tam olarak bu çekmecelerdir.

    Hızlı kontrolOrta

    Her sipariş durumu için bir sayaç tutacaksın. Hangi yapı en uygunudur?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Bir bankada para birimleri ve transfer tipleri tam böyle yazılır: her seçenek kendi kuralını taşır, hesaplama switch’e değil seçeneğin kendisine sorulur.

    Derinleş · Transfer tipi ve veritabanında saklamak 3 dosya · ~43 satır · ilk okumada atlayabilirsin
    Proje dosyaları

    src/main/java/com/bank/transfer/ TransferType.java Her tip kendi ücretini ve saat kuralını taşır. Ücretler örnektir, gerçek bir bankanın tarifesi değildir.

    src/main/java/com/bank/transfer/TransferType.java
    public enum TransferType {
    FAST(new BigDecimal("0.00"), true),
    EFT(new BigDecimal("4.50"), false),
    SWIFT(new BigDecimal("25.00"), false);
    private final BigDecimal fee;
    private final boolean alwaysOpen;
    TransferType(BigDecimal fee, boolean alwaysOpen) {
    this.fee = fee;
    this.alwaysOpen = alwaysOpen;
    }
    public BigDecimal fee() {
    return fee;
    }
    // EFT and SWIFT only run in banking hours in this example.
    public boolean availableAt(LocalTime time) {
    return alwaysOpen || (!time.isBefore(LocalTime.of(9, 0)) && time.isBefore(LocalTime.of(17, 0)));
    }
    }

    src/main/java/com/bank/transfer/ Transfer.java JPA'da enum sırayla değil adıyla saklanır.

    src/main/java/com/bank/transfer/Transfer.java
    @Entity
    public class Transfer {
    @Id
    @GeneratedValue
    private Long id;
    // STRING stores "EFT"; the default ORDINAL would store 1 and break if the order ever changed.
    @Enumerated(EnumType.STRING)
    private TransferType type;
    private BigDecimal amount;
    }

    src/main/java/com/bank/ Main.java Kullanım ve çıktı yorumlarda.

    src/main/java/com/bank/Main.java
    public class Main {
    public static void main(String[] args) {
    TransferType type = TransferType.valueOf("eft".toUpperCase(Locale.ROOT));
    System.out.println(type.fee()); // 4.50
    System.out.println(type.availableAt(LocalTime.of(20, 0))); // false
    System.out.println(TransferType.FAST.availableAt(LocalTime.of(20, 0))); // true
    }
    }

    Tuzaklar

    Veritabanına sıra numarası yazmak. JPA’da @Enumerated’ın varsayılanı sıra numarasıdır (ordinalBir enum sabitinin listedeki sıfırdan başlayan sırası. İlk sabitin ordinal değeri 0'dır.Liste değişince değişir; bu yüzden kalıcı bir kimlik olarak (veritabanında, dosyada) kullanılmaz. Kalıcı olan sabitin adıdır: name().Sözlükte gör →). Enum’un ortasına yeni bir sabit eklersen eski kayıtların anlamı kayar; bu yüzden EnumType.STRING kullan.

    Kullanıcı girdisini doğrudan valueOf’a vermek. Bilinmeyen bir değer IllegalArgumentException atar ve bu, kullanıcıya 500 hatası olarak dönebilir. Hatayı yakalayıp 400 olarak anlamlı bir mesajla dön.

    Switch’e default yazmak. Default, yeni eklenen bir sabiti sessizce yutar. Enum üzerindeki switch ifadesinde default yazmazsan derleyici eksik seçeneği gösterir.

    Hızlı kontrolOrta

    Bir JPA entity'sindeki enum alanında `@Enumerated` belirtilmemiş. Enum'un ortasına yeni bir sabit eklenince ne olur?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Kendini sına

    Şimşek turu1/4

    Enum'da olmayan bir sabiti yazmak çalışma anında hata verir.

    Soru 1/3Başlangıç

    Enum sabitlerinin kendi alanları ve metotları olabilir mi?

    Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

    Aklında kalacak üç şey

    1. 1 enum bir değerin alabileceği seçenekleri baştan sayar; listede olmayan bir değer derlenmez.
    2. 2 Enum bir sınıftır: her sabit kendi alanlarını ve davranışını taşıyabilir, böylece if-else zincirleri enum'un içine taşınır.
    3. 3 Enum'u veritabanına sıra numarasıyla değil adıyla yazarsın; araya yeni bir sabit eklemek eski kayıtların anlamını değiştirmemeli.
    Sonraki kapı İki Integer'ı karşılaştırdın: 127'de eşit çıktılar, 128'de çıkmadılar. Sayılar mı değişti? int ve Integer — Kutulu ve Kutusuz Sayılar · 8 dk

    3 kart sonraki derste seni bekliyor

    0/3 kart bu dersten toplandı