2011-03-21 16 views

Respuesta

58

No puede configurarlo. Siempre es el ordinal de la definición constante. Ver el documentation for Enum.ordinal():

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

Y en realidad, no debería necesitarlo. Si desea una propiedad entera, defina una.

+5

Si puedo especificar el ordinal de enumeración, cuando el uso de la APP con enumeración, que será más seguro ... –

75

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

enum Foo { 
    BAR(3), 
    BAZ(5); 
    private final int val; 
    private Foo(int v) { val = v; } 
    public int getVal() { return val; } 
} 

En esta situación BAR.ordinal() == 0, pero BAR.getVal() == 3.

+7

1 excepto que esta ISN Es una solución, de verdad. es el comportamiento deseado. el valor ordinal se considera un artefacto de implementación; si quiere asignar un entero u otro valor, eso es lo que "enums son clases" es tan bueno ... – andersoj

+1

no BAR.ordinal() return 0 afaik enum los índices están basados ​​en cero – Terraego

+0

@Terraego Good catch. – Matt

2

De http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Enum.html

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

Devuelve: la ordinales de esta constante de enumeración

Si tiene

Día public enum { Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado }

luego SUNDAY tiene un ordinal de 0, LUNES es 1, y así sucesivamente ...

+3

ortinal no se garantiza que realice el pedido anterior. – claj

+1

@claj, ¿puedes ampliar un poco? La documentación parece indicar que sí. – Celos

+0

Lo sentimos @Celos, la primera enumeración es de hecho 0, pero la especificación no menciona cómo debe asignarse el valor, aparte de ser monótonamente creciente. Creo que leí algo sobre esta advertencia en Java efectivo, pero no creo en mi palabra. – claj

0

Mira la Enum examples Java y docs

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

-2

La respuesta fácil: simplemente cambie el orden de las constantes. La primera definición será 0, la segunda será 1, etc. Sin embargo, esto puede no ser práctico si tiene un código que cambia constantemente, o las enumeraciones tendrán muchos valores. Puede definir un método personalizado para evitar el ordinal predeterminado, pero ASEGÚRESE de que esté bien documentado para evitar confusiones.

public enum Values 
{ 
    ONE, TWO, THREE, FOUR; 

    public int getCustomOrdinal() 
    { 
     if(this == ONE) 
     { 
      return 3; 
     } 
     else if(this == TWO) 
     { 
      return 0; 
     } 
     ... 
    } 
} 
+4

+1: Una instrucción switch puede ser mejor que una serie de sentencias if-else. –

+4

No me gusta esta solución. Los enumerados son clases y, por lo tanto, pueden contener propiedades personalizadas. Prefiero definir correctamente un campo para esto y un método getter correspondiente. – Atmocreations

+0

Esa es la mejor solución en general. Pero la pregunta era si era posible cambiar el comportamiento de ordinal() ... – donnyton

4

Puede actualizar ordinal utilizando la reflexión:

private void setEnumOrdinal(Enum object, int ordinal) { 
    Field field; 
    try { 
     field = object.getClass().getSuperclass().getDeclaredField("ordinal"); 
     field.setAccessible(true); 
     field.set(object, ordinal); 
    } catch (Exception ex) { 
     throw new RuntimeException("Can't update enum ordinal: " + ex); 
    } 
} 
1

Como la respuesta aceptada señala, no se puede establecer el ordinal. Lo más cerca que se puede llegar a esto es con una propiedad personalizada:

public enum MonthEnum { 

    JANUARY(1), 
    FEBRUARY(2), 
    MARCH(3), 
    APRIL(4), 
    MAY(5), 
    JUNE(6), 
    JULY(7), 
    AUGUST(8), 
    SEPTEMBER(9), 
    OCTOBER(10), 
    NOVEMBER(11), 
    DECEMBER(12); 

    MonthEnum(int monthOfYear) { 
     this.monthOfYear = monthOfYear; 
    } 

    private int monthOfYear; 

    public int asMonthOfYear() { 
     return monthOfYear; 
    } 

}