Dúvida com Enum

Ola pessoal,

Tenho a seguinte Enum:

[code] 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;
    }
}[/code]

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

Voce pode fazer isso…

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

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…

[code]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

[/code]

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:

[code] 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;

    }[/code]

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

Dessa forma pode eliminar o SWITCH/CASE

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

}[/code]

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.

Olá,

Acho que ficou um pouco melhor agora

[code] 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))) ;[/code]

Isso mesmo marcobiscaro2112!

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

Obrigado

[quote=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.[/quote]

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.