Come convertire il valore enum in int?


240

Ho una funzione che restituisce un tipo int. Tuttavia, ho solo un valore dell'enumerazione TAX.

Come posso trasmettere il valore di enumerazione TAX 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;
}

1
Possibile duplicato di Come abbinare int a enum
malat

Risposte:


354

Dovresti far esporre l'enum in valuequalche modo, ad es

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();
}

(Ho cambiato i nomi per essere un po 'più convenzionale e leggibile, tra l'altro.)

Ciò presuppone che si desideri assegnare il valore nel costruttore. Se non è quello che vuoi, dovrai darci maggiori informazioni.


1
@likejiujitsu: sta andando nella direzione opposta. In questa domanda, l'OP ha già un valore di tipo Taxe desidera ottenere da esso il valore numerico.
Jon Skeet,

L'ho appena provato e ho capito che myEnumValue = MyEnum.valueOf(myInt);l'arg deve essere di tipo String - o c'è qualcosa che mi manca?
likejudo,

Questa soluzione è peggio di niente. Sembra che gli enum in Java non debbano essere usati? O JDK 1.8 è cambiato?
ebyrob

@ebyrob: dato il voto, sembra che molte persone non siano d'accordo con te, come faccio io. Se vuoi un set fisso di valori, gli enumerati vanno assolutamente bene.
Jon Skeet,

209

Preferisco questo:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

poi:

//cast enum to int
int color = Color.Blue.ordinal();

34
Ciò è errato / non raccomandato da Joshua Bloch nel suo libro Effective Java (2a edizione). Vedi articolo 31.
user504342

43
@ user504342 Non ho la 2a edizione del libro, quindi puoi darci un'idea del perché non è raccomandato?
likejudo,

17
2 motivi: uno, qualsiasi associazione tra i valori ordinali e le costanti si interromperà se vengono aggiunte nuove costanti e due i documenti API specificamente sconsigliano.
jordanpg,

8
Così pulito e perfetto. Vedo alcuni "non farlo" e "non raccomandato". Dovrò fare delle ricerche sul perché sia ​​considerato negativo. Alcuni dei campioni gonfiati sembrano cattivi IMO. Tanto lavoro per svolgere un compito così semplice.
Herb Meehan,

4
In una squadra, sei abbastanza sicuro che il tuo co-sviluppatore aggiungerà un valore nel mezzo (peggio all'inizio), o semplicemente li ordinerà perché non hanno nulla da fare e pasticciano completamente il codice usando.ordinal()
Michael Laffargue

18

Se si desidera il valore che si sta assegnando nel costruttore, è necessario aggiungere un metodo nella definizione enum per restituire quel valore.

Se si desidera un numero univoco che rappresenti il ​​valore enum, è possibile utilizzare ordinal().


2
Stai attento. Ci sono molti più schemi anti-sviluppo su cui fare affidamento ordinal()rispetto a casi d'uso validi per ordinal(). Se è necessario memorizzare un valore univoco per enum, quindi archiviare enum. Ci sono EnumSet, Elenchi di Enum, EnumMaps e quasi tutte le altre raccolte di Enum che potresti desiderare disponibili.
Edwin Buck,

1
@EdwinBuck: Va bene sottolineare che volevo solo menzionare l'esistenza ordinal()perché l'OP non ha chiarito cosa voleva che fosse effettivamente l'int.
Unholysampler,

Non ottenere ordinale. Si prega di controllare l'enum api al riguardo. Up-voto rimosso.
Hovercraft Full Of Eels

3
Mi chiedo quali siano i pensieri delle persone sull'uso ordinal()interno all'interno dell'enum stesso. Ad esempio, dire che ho un enum chiamato " Season", che contiene i valori Spring, Summer, Autumn, e Winter, ed è un metodo pubblico chiamato next()che restituisce values()[(ordinal() + 1) % 4] Esternamente, nessun codice vede mai il numero ordinale, e non ci sarà mai ulteriori membri in questo enum, quindi sembra un caso d'uso valido.
Darrel Hoffman,

1
@DarrelHoffman La mia sensazione è che farlo vada bene, dal momento che gli unici argomenti forti che vedo contro l'uso della ordinal()cerniera su un codice remoto vengono interrotti da modifiche alle costanti di enumerazione dell'enum. Se hai intenzione di modificare le costanti dell'enum dovresti essere già in quel file. La maggior parte delle enumerazioni sono piuttosto brevi e, in caso contrario, dovresti comunque controllare il file più accuratamente. In entrambi i casi dovresti probabilmente avere un test unitario relativo al tuo next()metodo.
Alan Hensley,

12

A volte l'approccio C # semplifica la vita nel mondo 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;

Per me questo è il modo più desiderabile di andare. Ottengo i vantaggi di enum (chiarezza del codice), un tipo di dati che è compatibile con DB, e non devo cercare 100 alternative di enum per farlo nel "modo Android". Semplice ed efficace
John Ward,

Bello. È come se l'enum java fosse completamente disconnesso dalla realtà di ciò per cui viene usato un enum ... specialmente se le persone iniziano a abusarne per cose come i singoli. Questo approccio ha lo svantaggio di non avere un modo semplice per ottenere tutti i valori.
Nyerguds,

Questo non ha lo svantaggio di provare a passare un valore enumatico a un metodo? Non è più possibile passare un XLINK a un metodo, perché non rappresenta nulla di concreto. Perdi la digitazione nel tuo metodo. La firma del metodo dovrebbe essere breve anziché XLINK.
Dustin Jensen,

2

Forse è meglio usare una rappresentazione String piuttosto che un numero intero, perché String è ancora valido se i valori vengono aggiunti all'enum. È possibile utilizzare il metodo name () dell'enum per convertire il valore enum in una stringa e il metodo valueOf () dell'enum per creare nuovamente una rappresentazione enum dalla stringa. L'esempio seguente mostra come convertire il valore enum in String e back (ValueType è un enum):

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");

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.
}

0

Un approccio un po 'diverso (almeno su Android) consiste nell'utilizzare l' annotazione IntDef per combinare un set di costanti int

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

Utilizzare come parametro di funzione:

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

o in una dichiarazione variabile:

@TAX int currentTax = IMPORTEDTAX;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.