try number nfe example catch java parsing exception exception-handling numberformatexception

java - nfe - ¿Es la captura de NumberFormatException una mala práctica?



numberformatexception nfe (7)

Tengo que analizar una Cadena que pueda asumir valores hexadecimales u otros valores no hexadecimales

0xff , 0x31 o A , PC , label , etc.

Yo uso este código para dividir los dos casos:

String input = readInput(); try { int hex = Integer.decode(input); // use hex ... } catch (NumberFormatException e) { // input is not a hex, continue parsing }

¿Puede este código ser considerado "feo" o difícil de leer? ¿Hay otras soluciones (quizás más elegantes)?

EDITAR: Quiero aclarar que (en mi caso) no existe una entrada incorrecta : solo necesito distinguir si es un número hexadecimal o no. Y para completar, estoy haciendo un assebler simple para DCPU-16 .


Depende del contexto, en muchos casos es malo, pero si va a ser un lugar con muchas posibilidades de tener una entrada incorrecta y tiene un valor predeterminado para configurarlo, entonces querrá atraparlo.


El manejo de excepciones es una parte integral (y una de las metas de diseño) del lenguaje de programación Java ... no debe rechazarlas solo porque piensa que son "feas".

Dicho esto, si desea una forma simple y legible de manejar NumberFormatException , puede considerar utilizar la clase NumberUtils lugar.

El toInt(String str, int defaultValue) convierte una String en un int , y devuelve un valor predeterminado si la conversión falla. Si la cadena es null , se devuelve el valor predeterminado.

NumberUtils.toInt(null, 1) = 1 NumberUtils.toInt("", 1) = 1 NumberUtils.toInt("1", 0) = 1

El método encapsula captura y manejo de excepciones, como se ve en el código fuente a continuación. Como resultado, el cliente solo necesita hacer una llamada a un solo método.

public static int toInt(String str, int defaultValue) { if(str == null) { return defaultValue; } try { return Integer.parseInt(str); } catch (NumberFormatException nfe) { return defaultValue; } }


Es lo mejor que puedes hacer. Un método devolverá algún tipo de indicador de éxito / error o arrojará una excepción, solo es una cuestión de cuál es más conveniente. Aquí Sun tomó la decisión por nosotros, así que no hay necesidad de un debate.

¡Lo que más me molesta acerca de esto es que la excepción incluirá un seguimiento de pila completo! En su caso particular, si está leyendo millones de estas cadenas, notará un desempeño pobre (completamente innecesario). Si le importa, puede considerar escribir su propio método (puede usar el código de Sun como guía). Luego puede decidir por sí mismo si desea usar una excepción o no. Si lo hace, tenga a mano una copia estática de la excepción y siempre lance para ahorrar tiempo de asignación. Y anule fillInStackTrace para que no haga nada y no tenga un rastro de pila sin sentido en su excepción.


No, no es una "mala práctica". Solo depende de la situacion.

Por ejemplo, como Android, si el usuario ingresa una cadena "123a" en un cuadro de texto que se supone que solo acepta números enteros, y luego se analiza, se generará una excepción que hará que la aplicación falle. En este caso, tendría mucho sentido capturar la excepción e invitar al usuario a volver a ingresar el texto.


Not about how good you code looks , pero how good your code works .......... Ya offcourse it should be readable, como dijo famosamente ...

Cualquier tonto puede escribir un código que la computadora puede entender, pero solo los grandes programadores escriben códigos que los humanos pueden entender.

Está perfectamente bien en algunos casos donde, necesitas tener tales excepciones en su lugar.

When you want to catch multiple exceptions which belong to the same inheritance tree, then create a try block, and multiple catch blocks from more specific to more abstract.

p.ej:

`Animal <--- Carnivores <--- Dog`

Ahora supongamos que hay una DogException, CarnivoresException, AnimalException .

Entonces debe ser así,

try{ // your code } catch(DogException d){} catch(CarnivoresException c){} catch( AnimalException a){}

Las capturas anteriores se han dividido en cascada de las más específicas a las más abstractas, de modo que la causa de la excepción es justa.

Si no hay herencia, entonces la captura puede estar en cualquier orden ...


En su caso, preferiría algo así como un método isHexDigit para usar NumberFormatException , a menos que haya algunas suposiciones que pueda hacer sobre el formato de sus datos: según su descripción, parece que no hay tales suposiciones sobre cuándo se encontrará con el hexágono. números vs. números no hex.

Esto se debe a que las excepciones se deben usar para manejar condiciones excepcionales , y si la expectativa de sus datos es: dígitos hexadecimales o no hexagonales, separados por espacios , entonces no hay nada excepcional en encontrar una ficha que no sea un dígito hexadecimal.

Además, el uso de la Excepción hace que el código sea menos legible: sin comentarios sobre los datos, oculta el hecho de que los dígitos intercalados no hexadecimales son aceptables y la entrada esperada.

Habiendo establecido esa preferencia, podría usar el manejo de excepciones para manejar este caso, y ciertamente veo un montón de código que lo hace. Mucha de la buena funcionalidad está lista para usted en esa combinación de decode / parseInt / NumberFormatException. No usaría esto sin un comentario explícito que explique claramente lo que estoy haciendo.


La suya es la segunda pregunta que he visto hoy preguntando sobre esto.

No, es perfectamente apropiado detectar esta excepción.

Y definitivamente es mejor forma de detectar una excepción más explícita (como "NumberFormatException") que una "Excepción" genérica.

EN MI HUMILDE OPINIÓN...

PD: Donde pones la excepción: en este nivel, o más arriba, es una pregunta diferente.

La regla de oro es "el nivel más bajo en el que sabes lo que sucedió y la mejor forma de recuperarse".

O, para decirlo de otra manera (citando de un enlace a continuación):

"Un método solo debería detectar una excepción cuando puede manejarlo de una manera sensata".

Aquí hay algo de discusión: