Como converter um valor enum para int?

240

Eu tenho uma função que retorna um tipo int. No entanto, eu tenho apenas um valor da enumeração TAX.

Como converter o valor da enumeração TAX em um 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
fonte
1
Possível duplicata de Como combinar int para enum
malat 18/11/2016

Respostas:

354

Você precisaria fazer a enum expor de valuealguma forma, por exemplo

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

(Alterei os nomes para serem um pouco mais convencionais e legíveis, aliás.)

Isso pressupõe que você deseja o valor designado no construtor. Se não é isso que você deseja, precisará nos fornecer mais informações.

Jon Skeet
fonte
1
@likejiujitsu: Isso está indo na direção oposta. Nesta pergunta, o OP já possui um valor do tipo Taxe deseja obter o valor numérico dele.
21813 Jon Skeet
Eu apenas tentei e percebi que falha, myEnumValue = MyEnum.valueOf(myInt);o arg deve ser do tipo String - ou há algo que estou faltando?
likejudo
Esta solução é pior que nada. Parece que enums em Java simplesmente não devem ser usadas? Ou o JDK 1.8 mudou isso?
Ebyrob 11/11/16
@ebyrob: Dada a votação, parece que muitas pessoas discordam de você, como eu. Se você deseja um conjunto fixo de valores, as enumerações são absolutamente boas.
precisa
209

Eu prefiro isso:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

então:

//cast enum to int
int color = Color.Blue.ordinal();
vivia
fonte
34
Isso está incorreto / não é recomendado por Joshua Bloch em seu livro Effective Java (2nd ed). Veja o item 31.
user504342 13/10
43
@ user504342 Não tenho a 2ª edição do livro, então você pode nos dar uma ideia do porquê não é recomendado?
likejudo 10/09
17
2 razões: uma, qualquer associação entre os valores ordinais e as constantes será interrompida se novas constantes forem adicionadas e duas que os documentos da API recomendam especificamente contra ela.
Jordanpg # 28/14
8
Tão limpo e perfeito. Vejo alguns "não faça" e "não recomendado". Vou ter que pesquisar por que é considerado ruim. Algumas das amostras inchadas parecem ruins na IMO. Tanto trabalho para fazer uma tarefa tão simples.
Herb Meehan
4
Em uma equipe, você tem certeza de que seu co-desenvolvedor agregará um valor no meio (pior no início), ou apenas os classificará, porque eles não têm nada para fazer e estragam completamente o código usando.ordinal()
Michael Laffargue
18

Se você quiser o valor que está atribuindo no construtor, precisará adicionar um método na definição de enum para retornar esse valor.

Se você quiser um número único que representam o valor de enumeração, você pode usar ordinal().

unholysampler
fonte
2
Seja cuidadoso. Existem muitos antipadrões de desenvolvimento mais confiáveis ​​do ordinal()que os casos de uso válidos ordinal(). Se você precisar armazenar um valor exclusivo para o enum, basta armazenar o enum. Existem EnumSets, Listas de Enums, EnumMaps e quase qualquer outra coleção de Enum que você queira estar disponível.
Edwin Buck
1
@ EdwinBuck: É bom ressaltar, eu só queria mencionar a existência ordinal()porque o OP não deixou claro o que ele queria que o int fosse realmente.
Unholysampler
Não fique ordinal. Por favor, verifique a API do enum em relação a isso. Up-vote removido.
Hovercraft Cheio De Enguias
3
Eu me pergunto o que as pessoas pensam sobre o uso ordinal()interno do próprio enum. Por exemplo, digamos que eu tenho um enum chamado de " Season", que contém os valores Spring, Summer, Autumn, e Winter, e tem um método público chamado next()que retorna values()[(ordinal() + 1) % 4] Externamente, nenhum código nunca vê o número ordinal, e nunca haverá membros adicionais nesta enumeração, portanto, parece um caso de uso válido.
Darrel Hoffman
1
@DarrelHoffman Minha opinião é que fazer isso é bom, já que os únicos argumentos fortes que vejo contra o uso de ordinal()dobradiças em códigos distantes são quebrados por alterações nas constantes da enumeração de enumeração. Se você deseja modificar as constantes do enum, você já deve estar nesse arquivo. A maioria das enumerações é bastante curta e, caso contrário, você deve verificar o arquivo mais detalhadamente. Nos dois casos, você provavelmente deve ter um teste de unidade cobrindo seu next()método de qualquer maneira.
27675 Alan Hensley
12

Em algum momento, uma abordagem em C # facilita a vida no 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
fonte
Para mim, este é o caminho mais desejável. Recebo os benefícios do enum (clareza de código), um tipo de dados que é compatível com o banco de dados e não preciso pesquisar 100 alternativas de enum para fazer isso da "maneira android". Simples e eficaz.
John Ward
Agradável. É como se o java enum estivesse completamente desconectado da realidade para a qual um enum é usado ... especialmente se as pessoas começarem a abusar dele por coisas como singletons. Essa abordagem tem a desvantagem de não ter uma maneira fácil de obter todos os valores.
Nyerguds
Isso não tem a desvantagem de tentar passar um valor enum para um método? Você não pode mais passar um XLINK para um método, porque ele não representa nada concreto. Você perde a digitação no seu método. A assinatura do método teria que ser curta, em vez de XLINK.
Dustin Jensen
2

Talvez seja melhor usar uma representação String do que um número inteiro, porque a String ainda é válida se valores forem adicionados à enumeração. Você pode usar o método name () da enumeração para converter o valor da enumeração em String e o método valueOf () da enumeração para criar uma representação da enumeração da String novamente. O exemplo a seguir mostra como converter o valor da enumeração em String e vice-versa (ValueType é uma enumeração):

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");
Mike
fonte
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
fonte
0

Uma abordagem um pouco diferente (pelo menos no Android) é usar a anotação IntDef para combinar um conjunto de constantes int

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

Use como parâmetro de função:

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

ou em uma declaração variável:

@TAX int currentTax = IMPORTEDTAX;
mir
fonte