2010-09-29 2 views
88

Ich habe eine Enum SOME_ENUM:enum.values ​​() - ist ein Auftrag der zurück Aufzählungen determinis

public enum SOME_ENUM { 
    EN_ONE, 
    EN_TWO, 
    EN_THREE; 
} 

Will SOME_ENUM.values() immer geben die Aufzählungen in der Größenordnung von Enum Erklärungen: EN_ONE, EN_TWO, EN_THREE? Ist es eine Regel oder wird nicht garantiert, dass sie in den nächsten JDK-Versionen nicht geändert wird?

+1

warum würden Sie sich darauf verlassen? –

+1

Ich iteriere über meine Enum, um eine Liste zu füllen, die an anderer Stelle im Code, den ich gelesen habe, über diese Enumeration iteriert. – Skarab

+11

@MitchWheat Aus dem gleichen Grund, dass Sie sich auf eine Liste Erhaltung der Reihenfolge verlassen würden: weil das JDK ein Werkzeug ist, das Ihnen bestimmte Garantien gibt und sich auf diese Garantien stützt, hilft Ihnen, prägnanter und besser Code zu schreiben. Zugegeben, die Frage "Wird garantiert nicht verändert?" ist unmöglich zu beantworten, man kann sich sicher nicht darauf verlassen, nichts hat diese Garantie. – Fletch

Antwort

126

Die Java-Sprachspezifikation verwendet diese eindeutige Sprache:

@return ein Array mit den Konstanten dieses enum-Typs, in der Reihenfolge, wie sie sind [Source] erklärt

Also, ja , werden sie in der Reihenfolge der Erklärung zurückgegeben. Es ist erwähnenswert, dass sich die Reihenfolge im Laufe der Zeit ändern kann, wenn jemand die Klasse ändert, also sei sehr vorsichtig damit, wie du das verwendest.

+1

Wenn jemand einen Wert in der Mitte in einer späteren Codeversion hinzufügt, könnte dies zu einer Erhöhung führen, da dies den Ordnungswert anderer Elemente ändern würde (siehe Methode Enum.ordinal()). Es ist am besten, sich aus diesem Grund nicht auf die ordinale Position als Serialisierungsmechanismus zu verlassen (dh sie nicht in der db zu speichern). – Matt

+1

Link zur Quelle für diese Spezifikation? – screenmutt

+0

[Java 8 doc] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3) –

14

Ja, es ist garantiert, sie in dieser Reihenfolge zurückzugeben.

Sie sollten jedoch vermeiden, sich darauf verlassen, und auf dem ordinal() Wert, da es zum Beispiel nach dem Einfügen neuer Elemente ändern kann.

+0

+1 für den weisen Rat.Zum Thema ordinal() empfiehlt Effective Java, dem Enum-Typ ein Member-Feld hinzuzufügen. – ide

9

Es wird durch die Reihenfolge, in der Ihre Werte deklariert sind, festgelegt. gibt es jedoch keine Garantie, dass Sie (oder jemand anderes) keine Werte in der Zukunft neu anordnen/einfügen/entfernen. Also solltest du dich nicht auf die Bestellung verlassen.

Effektive Java 2nd. Ausgabe widmet seine Artikel 31 mit einem eng verwandten Thema: Verwenden Instanzfelder statt ordinals:

niemals einen Wert, der mit einem Enum aus seiner Ordnungs abzuleiten; Speichern Sie es stattdessen in einem Instanzfeld.

+3

"Keine Garantie, dass jemand in Zukunft keine Werte nachbestellt" - aber genau deshalb möchte ich mich auf die Bestellung verlassen :-)! Ich möchte in der Lage sein, die Artikel in Zukunft neu zu bestellen und dadurch das Verhalten meines Programms zu ändern. Bloch hat recht, wenn er sich nicht auf die Ordinalzahl verlässt und wenn das Beispiel des Fragestellers Enums wie EN_TWO beinhaltet, dann verlässt er sich auf die Ordinalzahl und sollte dies nicht tun. Aber sich auf die Bestellung zu verlassen, ist vollkommen in Ordnung. In der Tat, wie Reihenfolge ist garantiert, um ein Feld speziell für die Bestellung zu erstellen würde schreiben redundanten Code, die Art von Dingen Bücher wie Effective Java sagen Sie nicht zu tun. – Fletch

+0

@Fletch, sorry, ich folge dir nicht ganz. Für mich hört sich das so an, als würden Sie 'enum' für einen Zweck verwenden, für den es nicht gedacht war. –

+0

Nehmen wir an, Sie haben den berühmten "Planet" enum. In Ihrer Benutzeroberfläche möchten Sie die Planeten in der Reihenfolge ihrer Entfernung von der Sonne auflisten. Wie können Sie das am besten erreichen? Ich würde die Planetenkonstanten in der richtigen Reihenfolge innerhalb der enum-Klasse ordnen und dann einfach die enum in der UI aufzählen. Da die Bestellung zuverlässig ist, wird dies funktionieren. Davon rede ich. Wenn eines Tages die Erde der Sonne näher kommt als der Mars, dann ist natürlich in einem solchen Moment das erste, was in Ihrem warmen Geist die Aufrechterhaltung Ihres Codes ist! Also gehst du in deine Planet-Klasse und bewegst EARTH vor MARS. – Fletch

7

Die anderen Antworten sind gut, aber nicht kommentieren dies:

„Ist es eine Regel oder ist es nicht in den nächsten Jdk veröffentlicht wird nicht geändert garantiert?“

Ich glaube nicht, dass Garantien für zukünftige JDKs existieren, also sollten Sie sich nicht einmal darum kümmern. Es gäbe keine Möglichkeit, sie durchzusetzen, zukünftige JDK-Leads könnten sich einfach dafür entscheiden, solche Garantien zu verweigern. Es ist wie im Westminster-System des Parlaments: "Kein Parlament kann ein zukünftiges Parlament binden."

Das heißt, die Geschichte des JDK zeigt ausgezeichnete Konsistenz. Sie machen nicht viele brechende Änderungen, so dass Sie ziemlich sicher sein können, dass das aktuelle spezifizierte (nicht nur beobachtet) Verhalten beibehalten wird.