2010-09-29 7 views
88

Tengo una enumeración SOME_ENUM:enum.values ​​() - es una orden de enumeraciones devueltos determinista

public enum SOME_ENUM { 
    EN_ONE, 
    EN_TWO, 
    EN_THREE; 
} 

Will SOME_ENUM.values() siempre devuelven las enumeraciones en el orden de las declaraciones de enumeración: EN_ONE, EN_TWO, EN_THREE? ¿Es una regla o no está garantizado que no se modifique en las próximas versiones de JDK?

+1

¿por qué confiaría en él? –

+1

I itere sobre mi enumeración para completar una lista, que en otro lugar del código que he leído iterando sobre esta enumeración. – Skarab

+11

@MitchWheat Por la misma razón que confiaría en un pedido de conservación de listas: porque el JDK es una herramienta que le da ciertas garantías y confiar en estas garantías le ayuda a escribir códigos más concisos y mejores. Es cierto que la pregunta "¿Se garantiza que no se cambiará?" Es imposible responder, ciertamente no se puede confiar en eso, nada tiene esa garantía. – Fletch

Respuesta

126

La especificación del lenguaje Java utiliza este lenguaje explícito:

@return una matriz que contiene las constantes de este tipo de enumeración, en el orden en que se declaran [Source]

Así que, sí , serán devueltos en orden de declaración. Vale la pena señalar que la orden puede cambiar con el tiempo si alguien cambia la clase, así que ten mucho cuidado con la forma de usarla.

+1

Si alguien agrega un valor en el medio en una versión de código posterior, esto podría manguerarte, ya que cambiaría el valor ordinal de otros elementos (consulta el método Enum.ordinal()). Lo mejor es no confiar en la posición ordinal como un mecanismo de serialización (es decir, no almacenarlo en el DB) por este motivo. – Matt

+1

¿Enlace a la fuente para esa especificación? – screenmutt

+0

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

14

Sí, está garantizado devolverlos en ese orden.

Sin embargo, debe evitar confiar en eso, y en el valor ordinal(), ya que puede cambiar después de insertar nuevos elementos, por ejemplo.

+0

+1 para el consejo sabio.Sobre el tema de ordinal(), Effective Java sugiere agregar un campo miembro al tipo enum. – ide

9

Está determinado por el orden en que se declaran sus valores. Sin embargo, no hay garantía de que usted (u otra persona) no vuelva a ordenar/insertar/eliminar valores en el futuro. Entonces no debes confiar en la orden.

Effective Java 2nd. Edición dedica su artículo 31 a un tema muy relacionado: Use campos de instancia en lugar de los ordinales:

Nunca derivar un valor asociado con una enumeración de su ordinal; guárdelo en un campo de instancia en su lugar.

+3

"no hay garantía de que alguien no reordene los valores en el futuro", pero es exactamente por eso que quiero confiar en el pedido :-)! Quiero poder volver a ordenar los artículos en el futuro y, por lo tanto, cambiar el comportamiento de mi programa. Bloch tiene razón acerca de no confiar en el ordinal y si el ejemplo del solicitante realmente involucra enumeraciones como EN_TWO, entonces él está confiando en el ordinal y no debería hacer esto. Pero confiar en el orden está perfectamente bien. De hecho, como el orden está garantizado, crear un campo específico para el pedido sería escribir código redundante, el tipo de cosas que libros como Effective Java te dicen que no hagas. – Fletch

+0

@Fletch, lo siento, no te sigo del todo. Para mí esto suena como si estuvieras tratando de usar 'enum' para algún propósito para el que no fue diseñado. –

+0

digamos que tiene la famosa enumeración "Planeta". En su UI, desea enumerar los planetas en el orden de su distancia del sol. ¿Cómo puedes lograr esto? Pediría las constantes del planeta en el orden correcto dentro de la clase enum y luego simplemente enumeraría la enumeración en la IU. Dado que la orden es confiable, esto funcionará. Ese es el tipo de cosas de las que estoy hablando. Si un día la Tierra se acerca más al Sol que Marte, por supuesto que en ese momento lo primero que mantendrá en tu mente cálida será mantener tu código. Entonces vas a tu clase Planet y mueves a EARTH antes de MARS. – Fletch

7

Las otras respuestas son buenas, pero no hacen ningún comentario sobre esto: "¿Es una regla o que no se garantiza que no se puede cambiar en la próxima Jdk libera"

No creo que existan garantías sobre futuros JDK, por lo que ni siquiera debería preocuparse por ellos. No habría forma de hacerlos cumplir, los futuros líderes JDK podrían decidir renegar de tales garantías. Es como el sistema del parlamento de Westminster: "Ningún Parlamento puede obligar a un futuro parlamento".

Dicho esto, la historia del JDK revela una excelente coherencia. No hacen muchos cambios bruscos, por lo que puede estar seguro de que se conservará el comportamiento especificado (no solo observado).

Cuestiones relacionadas