Tengo la siguiente situación ejemplo:
public void shouldReturnStringForEnum() {
MessageType myType = getType();
System.out.println(getMessageForType(myType));
}
String getMessageForType(MessageType myType) {
switch(myType) {
case error:
return "Error type";
case warning:
return "Warning type";
case info:
return "Info type";
}
} // <= error: missing return statement
MessageType getType() {
Random random = new Random();
return MessageType.values()[random.nextInt(3)];
}
enum MessageType {error, warning, info }
No puedo imaginar qué es la posibilidad de volver del método getMessageForType
de otra manera que desde el cuerpo del switch
comunicado. Estaba pensando en:
- de-serialización de los datos de E / S - pero luego
java.lang.IllegalArgumentException: No enum constant
pasará mucho tiempo antes de que la llamadagetMessageForType
- parámetro posible método nula - pero entonces se producirá un error en
switch(myType)
la evaluación conjava.lang.NullPointerException
Forzar a una instrucción de retorno por defecto es incómodo en este tipo de situaciones, porque no sé qué para volver aquí. Lanzar una excepción en tal caso tampoco tiene sentido aquí. ¿Cuál es la decisión de diseño detrás de ese comportamiento?
Por favor ayuda, lo que me estoy perdiendo aquí?
Java obligando instrucción de retorno por defecto del método con el interruptor de enumeración con todos los valores de enumeración cubiertos ... ¿Cuál es la decisión de diseño detrás de ese comportamiento?
Esta es una decisión muy importante (y correcta) hecha por el lenguaje. A pesar de que los mangos de todos los códigos actuales de los valores actuales de la enumeración, que no quiere decir que la clase de enumeración podría cambiar mucho después de su código se compila. Es posible actualizar una biblioteca tercera parte y se puede añadir otro valor de enumeración causando que su código sea válido en tiempo de ejecución sin el defecto.
Aunque controle el código de enumeración que no quiere decir que otro desarrollador (o futuro) podrían añadir otro valor a la enumeración y no actualizar la sentencia switch. Escribir código que es compatible con versiones posteriores de esta manera es generalmente una buena práctica y en este caso crítico para el idioma para forzar el comportamiento.
No sé lo que para volver aquí.
La pregunta entonces se reduce a si se debe lanzar una excepción o no. Cómo manejar el valor de enumeración no válido u otras condiciones excepcionales es algo que nosotros como programadores lucha a diario. En este caso, es necesario preguntarse lo que usted quiere que suceda? Es una molestia que no debe ser desechado o se trata de un error más crítico? En caso de que la persona que llama manejar la excepción o es un RuntimeException
bien? Estas son las preguntas que debe responder en el contexto de su aplicación.
Por último, no sé sobre usted, pero la mayoría de los programadores que sé cortar y pegar una gran cantidad de código. Aunque esta enumeración no puede ser expandido, futuros enumeraciones se pueden expandir y hacer una buena decisión puede beneficiarse de manejar apropiadamente este caso.
Forzar a una instrucción de retorno por defecto es incómodo en este tipo de situaciones ...
"Unknown type"
podría ser una opción buena.
case ...:
return ...;
default:
// here in case someone updates the enum and forgets to update this code
return "Unknown type";
Lanzar una excepción en tal caso tampoco tiene sentido aquí.
Esto depende un poco de lo grande que un acuerdo de devolver el valor predeterminado "unknown"
cuerda. En el caso de que hay una nueva enumeración con una entrada faltante caso, habría que desea que una excepción o no?
Para excepciones, es posible que desee utilizar:
case ...:
return ...;
default:
throw new IllegalStateException("unknown enum type found for" + mType);
o tal vez IllegalArgumentException
.