enum.values ​​() - deterministik olarak döndürülen numaralandırmaların bir sırasıdır


105

Bir numaram var SOME_ENUM:

public enum SOME_ENUM {
  EN_ONE,
  EN_TWO,
  EN_THREE;
}

Will SOME_ENUM.values()hep enum bildirimleri sırayla Çeteleler dönüş: EN_ONE, EN_TWO, EN_THREE? Bu bir kural mı yoksa sonraki JDK sürümlerinde değiştirilmeyeceği garanti edilmiyor mu?


1
Bu numaralandırma üzerinde yineleyerek okuduğum koddaki diğer yerlere göre bir listeyi doldurmak için numaramı yineliyorum.
Skarab

11
@MitchWheat Liste koruma sırasına güvenmenizle aynı nedenden ötürü: çünkü JDK size belirli garantiler veren bir araçtır ve bu garantilere güvenmek, daha kısa ve daha iyi kod yazmanıza yardımcı olur. Kuşkusuz, "Değiştirilmemesi garantili mi?" Cevap vermek imkansızdır, buna kesinlikle güvenemezsiniz, hiçbir şeyin bu garantisi yoktur.
Fletch

Yanıtlar:


144

Java dil spesifikasyonu, bu açık dili kullanır:

@ Bu enum türünün sabitlerini bildirildikleri sırayla içeren bir diziyi geri döndürün [Kaynak]

Yani evet, beyan sırasına göre iade edilecekler. Birisi sınıfı değiştirirse sıranın zamanla değişebileceğini belirtmekte fayda var, bu yüzden bunu nasıl kullandığınıza çok dikkat edin.


1
Birisi daha sonraki bir kod sürümünde ortada bir değer eklerse, diğer öğelerin sıra değerini değiştireceği için bu durum sizi rahatsız edebilir (bkz. Enum.ordinal ()) yöntemi. En iyisi, bu nedenle sıralı konuma bir serileştirme mekanizması olarak güvenmemek (yani, onu db'de saklamamak).
Matt

1
Bu spesifikasyon için kaynağa bağlanılsın mı?
Dan Grahn


16

Evet, bu sırayla iade edilmesi garantilidir.

Bununla birlikte ordinal(), örneğin yeni öğeler ekledikten sonra değişebileceği için buna ve değere güvenmekten kaçınmalısınız .


Bilge tavsiyesi için +1. Ordinal () konusunda, Etkili Java, sıralama türüne bir üye alanı eklemeyi önerir.
ide

9

Değerlerinizin beyan edilme sırasına göre belirlenir. Ancak, sizin (veya bir başkasının) gelecekte değerleri yeniden sıralamayacağınızın / eklemeyeceğinizi / kaldırmayacağınızın garantisi yoktur . Bu yüzden siparişe güvenmemelisin.

Etkili Java 2nd. Edition, Madde 31'i yakından ilgili bir konuya ayırır : Sıra yerine örnek alanlarını kullanın :

Bir enum ile ilişkili bir değeri hiçbir zaman ordinalinden türetmeyin; bunun yerine bir örnek alanında saklayın.


3
"Birisinin gelecekte değerleri yeniden sıralayamayacağının garantisi yok" - ama tam da bu yüzden siparişe güvenmek istiyorum :-)! Gelecekte öğeleri yeniden sipariş edebilmek ve böylece programımın davranışını değiştirebilmek istiyorum. Bloch, sıraya güvenmemek konusunda haklıdır ve soran kişinin örneği gerçekten EN_TWO gibi numaralandırmaları içeriyorsa, o zaman sıralıya güveniyordur ve bunu yapmamalıdır. Ancak düzene güvenmek tamamen iyidir. Aslında, sipariş garanti edildiği için, özellikle sipariş için bir alan oluşturmak gereksiz kod yazmak olacaktır, Etkili Java gibi kitapların size yapmamanızı söylediği türden bir şey.
Fletch

@Fletch, üzgünüm seni tam olarak takip etmiyorum. Bana göre bu enum, amaçlanmadığı bir amaç için kullanmaya çalışıyorsunuz gibi geliyor .
Péter Török

ünlü "Gezegen" numarasına sahip olduğunuzu varsayalım. Kullanıcı arayüzünüzde gezegenleri güneşe olan uzaklıklarına göre listelemek istiyorsunuz. Bunu en iyi nasıl başarabilirsin? Gezegen sabitlerini enum sınıfının içinde doğru sırayla sıralar ve sonra sadece kullanıcı arayüzünde numaralandırırım. Sipariş güvenilir olduğu için bu işe yarayacaktır. Bahsettiğim türden bir şey bu. Dünya bir gün güneşe Mars'tan daha yakın hareket ederse, elbette böyle bir anda sıcak zihninizdeki ilk şey kodunuzu korumak olacaktır! Böylece Planet sınıfınıza gidin ve DÜNYAYI MARS'tan önceye hareket ettirin.
Fletch

@Fletch, Dünya zaten Güneş'e Mars'tan daha yakın ;-) ama ne demek istediğini anladım. Bununla birlikte, bu durumda gezegenlerin sırası, aslında basit bir sıra olmayan Güneş'e olan ortalama uzaklıklarının bir fonksiyonudur, bu nedenle IMHO, her gezegen için ayrı bir alan olarak saklanmalıdır. O zaman önemsiz bir karşılaştırıcıya gezegenleri Güneş'ten ortalama uzaklıklarına göre karşılaştırabilir ve bu karşılaştırıcıyı kullanarak onları sıralayabilirsiniz. Bu IMHO temiz ve kusursuz bir çözümdür. Oysa yeni bir meslektaşınız gezegenlerin açıkça alfabetik sırayla listelenmesi gerektiğine karar verir vermez çözümünüz bozuluyor ;-)
Péter Török

1
Hahaha ermm evet, neyse hepsi bir komplo, Mars yok. Başlangıçta Satürn'ü kullanacaktım ama hangi gezegenlere yakın olduğunu hatırlayamadım, ancak Mars planı geri tepti :-). Her neyse ... bu durumda bir karşılaştırıcı iyi olurdu, ancak açıkçası daha fazla kod gerektirmenin dezavantajı var. Kaynak kod sıralamasına güveniyorsanız, bunu sınıf yorumlarında belgelemenin iyi bir şey olacağını düşünüyorum. Meslektaşınız bile okuyabilir.
Fletch

7

Diğer cevaplar güzel, ancak bu konuda yorum yapmayın:

"Bu bir kural mı yoksa sonraki Jdk sürümlerinde değiştirilmeyeceği garanti edilmiyor mu?"

Gelecekteki JDK'larda garantilerin var olduğuna inanmıyorum, bu yüzden onlar için endişelenmeyin bile. Bunları uygulamanın hiçbir yolu olmayacaktı, gelecekteki JDK liderleri bu tür garantilerden vazgeçmeye karar verebilir. Westminster parlamento sistemi gibi: "Hiçbir Parlamento gelecekteki bir parlamentoyu bağlayamaz."

Bununla birlikte, JDK'nın tarihi mükemmel bir tutarlılık ortaya koymaktadır. Çok fazla kırılma değişikliği yapmazlar, bu nedenle mevcut belirtilen (sadece gözlemlenen değil) davranışın korunacağından oldukça emin olabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.