utiliza usar obtener forma enumerar enumerado enumeraciones enumeracion enum ejemplo definir declarar cuál correcta como java enums coding-style verbose

java - obtener - ¿Es una buena práctica usar ordinal de enumeración?



enum java netbeans (9)

El uso de ordinal() se recomienda ya que los cambios en la declaración de la enumeración pueden afectar los valores ordinales.

ACTUALIZAR:

Vale la pena señalar que los campos de enumeración son constantes y pueden tener valores duplicados, es decir,

enum Family { OFFSPRING(0), PARENT(1), GRANDPARENT(2), SIBLING(3), COUSING(4), UNCLE(4), AUNT(4); private final int hierarchy; private Family(int hierarchy) { this.hierarchy = hierarchy; } public int getHierarchy() { return hierarchy; } }

Dependiendo de lo que planee hacer con la hierarchy esto podría ser perjudicial o beneficioso.

Además, podría usar las constantes de enumeración para construir sus propios EnumFlags lugar de usar EnumSet , por ejemplo

Tengo enumeración

public enum Persons { CHILD, PARENT, GRANDPARENT; }

¿Hay algún problema con el uso del método ordinal() para verificar la "jerarquía" entre los miembros de la enumeración? Quiero decir, ¿hay alguna desventaja cuando se usa excluyendo verbosidad, cuando alguien puede cambiar accidentalmente el orden en el futuro?

¿O es mejor hacer algo así?

public enum Persons { CHILD(0), PARENT(1), GRANDPARENT(2); private Integer hierarchy; private Persons(final Integer hierarchy) { this.hierarchy = hierarchy; } public Integer getHierarchy() { return hierarchy; } }


En primer lugar, es probable que ni siquiera necesite un valor de orden numérico: para eso es Comparable , y Enum<E> implementa Comparable<E> .

Si necesita un valor de orden numérico por algún motivo, sí, debe usar ordinal() . Para eso está.

La práctica estándar para las Enums Java es ordenar por orden de declaración, por lo que Enum<E> implementa Comparable<E> y la razón por la que Enum.compareTo() es final .

Si agrega su propio código de comparación no estándar que no usa Comparable y no depende del orden de la declaración, simplemente confundirá a cualquier otra persona que intente usar su código, incluido su propio yo futuro. Nadie va a esperar que ese código exista; van a esperar que Enum sea Enum .

Si la orden personalizada no coincide con la orden de declaración, cualquier persona que vea la declaración se confundirá. Si (en este momento, coincide) con la orden de declaración, cualquiera que lo vea llegará a esperar eso, y sufrirá una conmoción desagradable cuando no lo haga en una fecha futura. (Si escribe código (o pruebas) para asegurarse de que la orden personalizada coincida con la orden de declaración, simplemente está reforzando lo innecesario).

Si agrega su propio valor de pedido, está creando dolores de cabeza de mantenimiento para usted:

  1. necesita asegurarse de que los valores de su hierarchy son únicos
  2. Si agrega un valor en el medio, necesita renumerar todos los valores posteriores.

Si le preocupa que alguien pueda cambiar la orden accidentalmente en el futuro, escriba una prueba de unidad que verifique la orden.

En resumen, en las palabras inmortales del artículo 47 : conocer y usar las bibliotecas .

PS Además, no uses Integer cuando te refieres a int . 🙂


Esta no es una respuesta directa a tu pregunta. Más bien mejor enfoque para su caso de uso. De esta manera, se asegura de que el próximo desarrollador sepa explícitamente que los valores asignados a las propiedades no deben cambiarse.

Cree una clase con propiedades estáticas que simulará su enumeración:

public class Persons { final public static int CHILD = 0; final public static int PARENT = 1; final public static int GRANDPARENT = 2; }

A continuación, utilice como enumeración:

Persons.CHILD

Funcionará para los casos de uso más simples. De lo contrario, podría faltar en opciones como valueOf() , EnumSet , EnumMap o values() .


Según lo sugerido por Joshua Bloch en Effective Java , no es una buena idea derivar un valor asociado con una enumeración de su ordinal, porque los cambios en el orden de los valores de enumeración podrían romper la lógica que usted codificó.

El segundo enfoque que menciona sigue exactamente lo que propone el autor, que es almacenar el valor en un campo separado.

Diría que la alternativa que sugirió es definitivamente mejor porque es más ampliable y fácil de mantener, ya que está desacoplando el orden de los valores de enumeración y la noción de jerarquía.


Segun java doc

Devuelve el ordinal de esta constante de enumeración (su posición en su declaración de enumeración, donde a la constante inicial se le asigna un ordinal de cero). La mayoría de los programadores no tendrán ningún uso para este método. Está diseñado para ser utilizado por sofisticadas estructuras de datos basadas en enumeración, como EnumSet y EnumMap.

Puede controlar el ordinal cambiando el orden de la enumeración, pero no puede establecerlo explícitamente. Una solución es proporcionar un método adicional en su enumeración para el número que desea.

enum Mobile { Samsung(400), Nokia(250),Motorola(325); private final int val; private Mobile (int v) { val = v; } public int getVal() { return val; } }

En esta situación, Samsung.ordinal() = 0 , pero Samsung.getVal() = 400 .


Si se refiere al javadoc para el método ordinal en Enum.java :

La mayoría de los programadores no tendrán ningún uso para este método. Está diseñado para ser utilizado por estructuras de datos sofisticadas basadas en enumeración, como java.util.EnumSet y java.util.EnumMap .

En primer lugar - lea el manual (javadoc en este caso).

En segundo lugar - no escriba código frágil. Los valores de enumeración pueden cambiar en el futuro y su segundo ejemplo de código es mucho más claro y fácil de mantener .

Definitivamente, no desea crear problemas para el futuro si (por ejemplo) se inserta un nuevo valor de enumeración entre PARENT y GRANDPARENT .


Si solo desea crear relaciones entre los valores de enumeración, puede utilizar el truco de usar otros valores de enumeración :

public enum Person { GRANDPARENT(null), PARENT(GRANDPARENT), CHILD(PARENT); private final Person parent; private Person(Person parent) { this.parent = parent; } public final Parent getParent() { return parent; } }

Tenga en cuenta que solo puede usar valores enum que se declararon léxicamente antes de los que intenta declarar, por lo que esto solo funciona si sus relaciones forman un gráfico dirigido acíclico (y el orden en el que los declara es una clasificación topológica válida).


Yo usaría su segunda opción (usando un entero explícito) para que los valores numéricos sean asignados por usted y no por Java.


La primera forma no es directamente comprensible, ya que tiene que leer el código donde se utilizan las enumeraciones para comprender que el orden de las enumeraciones es importante.
Es muy propenso a errores.

public enum Persons { CHILD, PARENT, GRANDPARENT; }

La segunda forma es mejor ya que se explica por sí misma :

CHILD(0), PARENT(1), GRANDPARENT(2); private SourceType(final Integer hierarchy) { this.hierarchy = hierarchy; }

Por supuesto, los órdenes de los valores de enumeración deben ser consistentes con el orden jerárquico proporcionado por los argumentos del constructor de enumeración.

Introduce una especie de redundancia, ya que tanto los valores de enumeración como los argumentos del constructor de enumeración transmiten la jerarquía de ellos.
Pero ¿por qué sería un problema?
Las enumeraciones están diseñadas para representar valores constantes y no cambiantes con frecuencia .
El uso de enumeración OP ilustra bien un buen uso de enumeración:

CHILD, PARENT, GRANDPARENT

Las enumeraciones no están diseñadas para representar valores que se mueven con frecuencia.
En este caso, el uso de enums probablemente no sea la mejor opción, ya que puede romper con frecuencia el código del cliente que lo usa y además obliga a volver a compilar, volver a empaquetar y volver a implementar la aplicación en cada momento en que se modifique un valor de enum.