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

1

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.


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

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().


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;

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

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

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.