¿Cómo convertir el valor enum a int?

240

Tengo una función que devuelve un tipo int. Sin embargo, solo tengo un valor de la enumeración de impuestos.

¿Cómo puedo convertir el valor de enumeración de impuestos a un int?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

    private int value;
    private TAX(int value){
        this.value = value;
    }
}

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}
vrbilgi
fuente
1
Posible duplicado de Cómo combinar int con enum
malat

Respuestas:

354

Tendría que hacer que la enumeración se exponga de valuealguna manera, por ejemplo

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(He cambiado los nombres para que sean un poco más convencionales y legibles, por cierto).

Esto supone que desea el valor asignado en el constructor. Si eso no es lo que desea, deberá proporcionarnos más información.

Jon Skeet
fuente
1
@likejiujitsu: Eso va en la dirección opuesta. En esta pregunta, el OP ya tiene un valor de tipo Taxy desea obtener el valor numérico de él.
Jon Skeet
Acabo de probarlo y me doy cuenta de que falla myEnumValue = MyEnum.valueOf(myInt);el argumento tiene que ser de tipo String, ¿o hay algo que me falta?
likejudo
Esta solución es peor que nada. ¿Parece que las enumeraciones en Java no deberían usarse? ¿O JDK 1.8 ha cambiado eso?
ebyrob
@ebyrob: Dada la votación, parece que muchas personas no están de acuerdo contigo, como yo. Si desea un conjunto fijo de valores, las enumeraciones están absolutamente bien.
Jon Skeet
209

Prefiero esto:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

luego:

//cast enum to int
int color = Color.Blue.ordinal();
vivia
fuente
34
Esto es incorrecto / no recomendado por Joshua Bloch en su libro Effective Java (2nd ed). Ver artículo 31.
usuario504342
43
@ user504342 No tengo la segunda edición del libro, ¿puede darnos una idea de por qué no se recomienda?
likejudo
17
2 razones: una, cualquier asociación entre los valores ordinales y las constantes se romperá si se agregan nuevas constantes, y dos los documentos de la API recomiendan específicamente en su contra.
jordanpg
8
Muy limpio y perfecto. Veo algunos "no lo hagas" y "no recomendado". Tendré que investigar por qué se considera malo. Algunas de las muestras hinchadas se ven mal IMO. Tanto trabajo para hacer una tarea tan simple.
Herb Meehan
44
En un equipo, está bastante seguro de que su co-desarrollador agregará un valor en el medio (peor al principio), o simplemente los ordenará porque no tienen nada que hacer y desordenará completamente el código usando.ordinal()
Michael Laffargue
18

Si desea el valor que está asignando en el constructor, debe agregar un método en la definición de enumeración para devolver ese valor.

Si desea un número único que represente el valor de enumeración, puede usarlo ordinal().

muestreador
fuente
2
Ten cuidado. Hay muchos más antipatrones de desarrollo en los que se basan ordinal()los casos de uso válidos ordinal(). Si necesita almacenar un valor único para el enum, simplemente almacene el enum. Hay EnumSets, Listas de Enums, EnumMaps y casi cualquier otra colección de Enum que desee tener disponible.
Edwin Buck
1
@EdwinBuck: Eso es bueno señalar, solo quería mencionar la existencia de ordinal()porque el OP no dejó en claro qué quería que fuera realmente el int.
unholysampler el
No te pongas ordinal. Por favor, consulte la API de enumeración con respecto a esto. Voto a favor eliminado.
Aerodeslizador lleno de anguilas
3
Me pregunto qué piensan las personas sobre el uso de ordinal()internamente dentro del enum. Por ejemplo, decir que tengo una enumeración llamada " Season", que contiene los valores Spring, Summer, Autumn, y Winter, y tiene un método público denominado next()el cual devuelve values()[(ordinal() + 1) % 4] el exterior, hay un código cada vez ve el número ordinal, y nunca habrá miembros adicionales en esta enumeración, entonces parece un caso de uso válido.
Darrel Hoffman
1
@DarrelHoffman Mi sensación es que hacerlo está bien, ya que los únicos argumentos fuertes que veo en contra del uso de la ordinal()bisagra en el código remoto se rompen por los cambios en las constantes de enumeración de enumeración. Si va a modificar las constantes de la enumeración, ya debería estar en ese archivo. La mayoría de las enumeraciones son bastante cortas, y si no es así, debería verificar el archivo más a fondo de todos modos. En ambos casos, probablemente debería hacerse una prueba unitaria que cubra su next()método de todos modos.
Alan Hensley
12

En algún momento, un enfoque de C # hace la vida más fácil en el mundo Java ...:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;
Vladi
fuente
Para mí, este es el camino más deseable. Obtengo los beneficios de enum (claridad de código), un tipo de datos que es compatible con DB, y no tengo que investigar 100 alternativas de enum para hacerlo "a la manera de Android". Simple y efectivo.
John Ward,
Agradable. Es como si la enumeración de Java estuviera completamente desconectada de la realidad de para qué se utiliza una enumeración ... especialmente si las personas comienzan a abusar de ella para cosas como singletons. Sin embargo, este enfoque tiene la desventaja de que no tiene una manera fácil de obtener todos los valores.
Nyerguds
¿No tiene esto la desventaja de intentar pasar un valor enum a un método? Ya no puede pasar un XLINK a un método, porque no representa nada concreto. Pierdes la escritura en tu método. La firma del método tendría que leerse brevemente en lugar de XLINK.
Dustin Jensen
2

Quizás sea mejor usar una representación de cadena que un entero, porque la cadena sigue siendo válida si se agregan valores a la enumeración. Puede utilizar el método name () de la enumeración para convertir el valor de enumeración en una Cadena y el método valueOf () de la enumeración para crear una representación de enumeración a partir de la Cadena nuevamente. El siguiente ejemplo muestra cómo convertir el valor enum a String y viceversa (ValueType es una enumeración):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");
Miguel
fuente
1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}
Ieshaan Saxena
fuente
0

Un enfoque algo diferente (al menos en Android) es usar la anotación IntDef para combinar un conjunto de constantes int

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Usar como parámetro de función:

void computeTax(@TAX int taxPercentage){...} 

o en una declaración variable:

@TAX int currentTax = IMPORTEDTAX;
mir
fuente