Dúvida com Enum

8 respostas
P

Ola pessoal,

Tenho a seguinte Enum:

public static enum ReturnCode {
        NO_ERROR(0),  	// Nenhum erro ocorreu
        TIMEOUT(1),  	// Time out
        PAR_ERR(2),  	// Parametro incorreto
        COM_ERR(3),  	// Erro de comunicacao

        private int returnCode;

        private ReturnCode(int e) {
            returnCode = e;
        }

        public int getValue() {
            return returnCode;
        }
    }

Mas queria que ao receber o código de erro (Int) eu pudesse fazer um simples ValueOf() e obter a enum correspondente.

Tentei o óbvio:

ReturnCode returnCode = ReturnCode.valueOf(0);

Esperando que eu tivesse a constante NO_ERROR retornada, mas isso não funciona. Qual o jeito elegante para se contornar isso?

Acho que deve ser alguma bobeira que eu não estou sacando, pois não mexi com Enums em Java antes.

Alguém poderia me ajudar?

Obrigado

8 Respostas

Marky.Vasconcelos

Voce pode fazer isso…

ReturnCode returnCode = Enum.valueOf(ReturnCode.class,"NO_ERROR") ;
brunoccouto

Pelo que entendi, você precisa do nome da constante e nao do valor, certo?

No método Enum.valueOf(), o argumento esperado é uma string, o que corresponde ao nome da constante,

ReturnCode returnCode = ReturnCode.valueOf("NO_ERROR");

//O que gera a saida 0
System.out.println(returnCode.getValue());

Se voce precisa do nome da constante é só usar o método Enum.name();

ReturnCode returnCode = ReturnCode.valueOf("NO_ERROR");

//O que gera a saida "NO_ERROR"
System.out.println(returnCode.name);

Uma solução não muito convencional, mas que funcionaria perfeitamente...

enum ReturnCode {
        
        _0(0, "NO_ERROR"),
        _1(1, "TIME_OUT"),
        _2(2, "PAR_ERR"),
        _3(3, "COM_ERR");
    
        private int returnCode;
        private String returnName;
    
        private ReturnCode(int returnCode, String returnName) {
            this.returnCode = returnCode;
            this.returnName = returnName;
        }
        
        public int getCode() {
            return this.returnCode;
        };

        public String getName() {
            return this.returnName;
        }

}


ReturnCode returnCode = ReturnCode.valueOf("_1");
int code = returnCode.getCode(); // 1
String name = returnCode.getName(); // TIME_OUT
P

Obrigado pessoal,

Realmente Bruno, é mais ou menos isso que eu queria, só não entendi uma coisa, minha enumeration seria o _0, _1 e tudo mais?

Fica meio ilegível no código, não acha? Queria que o usuário da classe pudesse simplesmente escolher ReturnCode.TIME_OUT sem se preocupar se o código disso é 20 ou 65265. Mais ou menos do jeito que construí, o único problema que tenho mesmo é que não consigo a partir de um inteiro (que é retornado por um soquete) seja mapeado diretamente para sua enumeration correspondente. Tenho uma Switch/Case (que polui muito o código, na minha opinião) fazendo o mapeamento, algo como:

switch (Integer.parseInt(message.substring(9, 12))) {
            case 0:
                returnCode = ReturnCode.NO_ERROR;
                break;
            case 1:
                returnCode = ReturnCode.TIMEOUT;
                break;
            case 2:
                returnCode = ReturnCode.PAR_ERR;
                break;
            case 3:
                returnCode = ReturnCode.COM_ERR;
                break;
            default:
                returnCode = ReturnCode.NOT_DEFINED;
                break;

        }

Queria algo mais elegante. Esse código ficou mais chatinho para se manter que o necessário.

Acredito que deva existir uma solução mais simples. Alguém tem alguma outra sugestão?

Obrigado

brunoccouto
Dessa forma pode eliminar o SWITCH/CASE
package guj;

public class Enumeracoes {

    enum ReturnCode {

        CODE_0(0, "NO_ERROR"),
        CODE_1(1, "TIME_OUT"),
        CODE_2(2, "PAR_ERR"),
        CODE_3(3, "COM_ERR");
    
        private int returnCode;
        private String returnName;
    
        private ReturnCode(int returnCode, String returnName) {
            this.returnCode = returnCode;
            this.returnName = returnName;
        }
        
        public int getCode() {
            return this.returnCode;
        };

        public String getName() {
            return this.returnName;
        }

        // Esse metodo retorna um ReturnCode corresponde a 'code'
        public static ReturnCode getReturnCode(int code) {
            return ReturnCode.valueOf("CODE_" + code);
        }

    }

    public static void main(String[] args) {
        //Assim voce passa um inteiro e ele te retorna uma ReturnCode
        ReturnCode returnCode = ReturnCode.getReturnCode(1);
        System.out.println(returnCode.getName());
    }

}
M

Você pode fazer um for para resgatar o ReturnCode pelo código:

public static ReturnCode getReturnCode(int code) {
		for (ReturnCode r : ReturnCode.values()) {
			if (r.getValue() == code) {
				return r;
			}
		}
		throw new IllegalArgumentException("Valor não encontrado.");
	}

E só mais uma coisa: um enum não pode ter o modificador static, como no seu primeiro código postado.

P

Olá,

Acho que ficou um pouco melhor agora

public static enum ReturnCode {

        NO_ERROR(0), // Nenhum erro ocorreu   
        TIMEOUT(1), // Time out   
        PAR_ERR(2), // Parametro incorreto   
        COM_ERR(3); // Erro de comunicacao   
        private int returnCode;

        private ReturnCode(
                int e) {
            returnCode = e;
        }

        public int getValue() {
            return returnCode;
        }

        public static ReturnCode parse(int i) {
            for (ReturnCode r : values()) {
                if (r.getValue() == i) {
                    return r;
                }
            }

            return ReturnCode.NOT_DEFINED;
        }
    }

    ReturnCode returnCode = ReturnCode.parse(Integer.parseInt(message.substring(9, 12))) ;
P

Isso mesmo marcobiscaro2112!

Quando escrevi minha resposta não tinha visto a sua.

Obrigado

Marky.Vasconcelos

marcobiscaro2112:
Você pode fazer um for para resgatar o ReturnCode pelo código:

public static ReturnCode getReturnCode(int code) {
		for (ReturnCode r : ReturnCode.values()) {
			if (r.getValue() == code) {
				return r;
			}
		}
		throw new IllegalArgumentException("Valor não encontrado.");
	}

E só mais uma coisa: um enum não pode ter o modificador static, como no seu primeiro código postado.

Só um problema… aqui voce esta retirando a parte do switch/case e fazendo um for que vai passar em todos até encontrar… acho que a solução do bruno é melhor nessa parte… ou então guarde-os numa LinkedList e use um get(int index) que vai ter o objeto que voce quer com o numero indicado.

Criado 20 de fevereiro de 2009
Ultima resposta 21 de fev. de 2009
Respostas 8
Participantes 4