He escrito una función que le pide al usuario que ingrese hasta que el usuario ingrese un número entero positivo (un número natural). Alguien dijo que no debería lanzar y capturar excepciones en mi función y debería dejar que la persona que llama de mi función las maneje.
Me pregunto qué piensan otros desarrolladores sobre esto. Probablemente también estoy haciendo mal uso de excepciones en la función. Aquí está el código en Java:
private static int sideInput()
{
int side = 0;
String input;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("Side length: ");
input = scanner.nextLine();
try {
side = Integer.parseInt(input);
if (side <= 0) {
// probably a misuse of exceptions
throw new NumberFormatException();
}
}
catch (NumberFormatException numFormExc) {
System.out.println("Invalid input. Enter a natural number.");
}
} while (side <= 0);
return side;
}
Me interesan dos cosas:
- ¿Debo dejar que la persona que llama se preocupe por las excepciones? El punto de la función es que molesta al usuario hasta que el usuario ingrese un número natural. ¿Es malo el punto de la función? No estoy hablando de la interfaz de usuario (el usuario no puede salir del bucle sin la entrada adecuada), sino de la entrada en bucle con excepciones manejadas.
- ¿Diría que la declaración de lanzamiento (en este caso) es un mal uso de excepciones? Podría crear fácilmente una bandera para verificar la validez del número y enviar el mensaje de advertencia basado en esa bandera. Pero eso agregaría más líneas al código y creo que es perfectamente legible como es.
La cuestión es que a menudo escribo una función de entrada separada. Si el usuario tiene que ingresar un número varias veces, creo una función separada para la entrada que maneja todas las excepciones y limitaciones de formato.
exceptions
usr
fuente
fuente
Respuestas:
El punto de una excepción es que permite que un método le diga a la persona que llama que ingresó un estado en el que no puede continuar normalmente, sin obligarlo a incrustar un código de error en el valor de retorno.
En su caso, su método sabe exactamente qué hacer cuando la entrada no es mayor que 0. La única razón por la que está guardando líneas aquí es porque está lanzando la misma excepción que obtendría si la entrada no fuera un número. Sin embargo, la excepción que está lanzando no representa adecuadamente por qué su código no le gusta la entrada. Si alguien más apareciera y viera este código, tendrían que pasar más tiempo tratando de ver exactamente cómo funcionan las cosas.
fuente
Este es un mal uso de excepciones. Para empezar, un número no positivo no es una excepción de formato.
¿Por qué usar excepciones en absoluto? Si sabe qué entrada no está permitida, simplemente no salga del ciclo hasta que obtenga una entrada válida del usuario, algo como lo siguiente:
fuente
Integer.parseInt()
arroja unNumberFormatException
si no puede analizar el argumento de cadena proporcionado. No es necesario que usted (y no podrá) lanzar la excepción usted mismo.Integer.parseInt()
método arrojará la excepción para ti si ocurre, no podrás lanzarlo tú mismo después ya que ya se ha lanzado.Solo capture excepciones si tiene la intención de hacer algo que sea relevante para la llamada al método actual; es decir, limpieza, lógica de falla, etc. En este caso, la captura simplemente está enviando un mensaje a la consola, no es relevante para el método sideInput, por lo que puede manejarse más arriba en la cadena / pila de llamadas.
Uno puede deshacerse del try / catch aquí y simplemente documentar la llamada al método:
¡Todavía hay que manejar esa excepción más arriba en la cadena / pila de llamadas!
fuente
No debe lanzar y atrapar la misma excepción en un método, incluso creo que el bloque de captura capturará la misma excepción que está lanzando, por lo que realmente no lo está lanzando.
Si
parseInt
tuvo éxito, entonces no es unNumberFormatException
.si el lado es menor que cero, debe lanzar un
NegativeSideLengthException
;Cree una excepción personalizada / comercial denominada
NegativeSideLengthException
Luego
sideInput
lanza NegativeSideLengthExceptionIncluso puede (si lo desea) agregar otro bloque catch para atrapar
NegativeSideLengthException
y no hacer que el método lo lance.Las banderas no son una buena forma de manejar las excepciones.
fuente
Las excepciones son cosas bastante pesadillas, traen más complejidades de las que resuelven.
En primer lugar, si no detecta sus excepciones, la persona que llama solo puede hacer
on error resume next
, es decir, después de una semana, incluso usted no sabrá qué puede arrojar su función y qué hacer con ella:Básicamente, si los atrapa, debe comprender muy bien los contratos y las garantías de excepción. Eso rara vez sucede en un mundo real. Y también su código será difícil de leer.
Además, lo curioso es que si realmente tiene alguna posibilidad de manejar excepciones, necesita un lenguaje RAII real, que es algo gracioso, ya que Java y .NET se trata de excepciones ...
Repitiendo esto una vez más, pero ...:
http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
http://www.joelonsoftware.com/items/2003/10/13.html
fuente
: throw(thisexception, thatexception)
están francamente mal y nunca deben usarse, porque de lo contrario obtendrás una excepción inesperada.catch
. Si bien un valor de retorno ignorado no se puede buscar, solo se puede identificar a través de la revisión de código línea por línea. Por último, pero no menos importante, los constructores no tienen valores de retorno, esta es la razón principal para usar excepciones.