Comprender la excepción NumberFormatException en Java

1. Introducción

Java lanza NumberFormatException, una excepción no comprobada, cuando no puede convertir una cadena en un tipo de número.

Como está desmarcado, Java no nos obliga a manejarlo ni a declararlo.

En este tutorial rápido, describiremos y demostraremos qué causa NumberFormatException en Java y cómo evitarlo o tratarlo .

2. Causas de NumberFormatException

Hay varios problemas que causan NumberFormatException . Por ejemplo, algunos constructores y métodos en Java lanzan esta excepción.

Discutiremos la mayoría de ellos en las secciones siguientes.

2.1. Datos no numéricos pasados ​​al constructor

Veamos un intento de construir un objeto Integer o Double con datos no numéricos.

Ambas declaraciones arrojarán NumberFormatException :

Integer aIntegerObj = new Integer("one"); Double doubleDecimalObj = new Double("two.2");

Veamos el seguimiento de la pila que obtuvimos cuando pasamos la entrada inválida "uno" al constructor Integer en la línea 1:

Exception in thread "main" java.lang.NumberFormatException: For input string: "one" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.(Integer.java:867) at MainClass.main(MainClass.java:11)

Lanzó NumberFormatException . El constructor de Integer falló al intentar comprender la entrada usando parseInt () internamente.

La API de números de Java no analiza las palabras en números, por lo que podemos corregir el código simplemente cambiándolo a un valor esperado:

Integer aIntegerObj = new Integer("1"); Double doubleDecimalObj = new Double("2.2");

2.2. Análisis de cadenas que contienen datos no numéricos

Similar al soporte de Java para el análisis en el constructor, tenemos métodos de análisis dedicados como par seInt (), parseDouble (), valueOf () y decode () .

Si intentamos hacer los mismos tipos de conversión con estos:

int aIntPrim = Integer.parseInt("two"); double aDoublePrim = Double.parseDouble("two.two"); Integer aIntObj = Integer.valueOf("three"); Long decodedLong = Long.decode("64403L");

Entonces veremos el mismo tipo de comportamiento erróneo.

Y podemos solucionarlos de manera similar:

int aIntPrim = Integer.parseInt("2"); double aDoublePrim = Double.parseDouble("2.2"); Integer aIntObj = Integer.valueOf("3"); Long decodedLong = Long.decode("64403");

2.3. Pasar cadenas con caracteres extraños

O, si intentamos convertir una cadena en un número con datos extraños en la entrada, como espacios en blanco o caracteres especiales:

Short shortInt = new Short("2 "); int bIntPrim = Integer.parseInt("_6000");

Entonces, tendremos el mismo problema que antes.

Podríamos corregirlos con un poco de manipulación de cadenas:

Short shortInt = new Short("2 ".trim()); int bIntPrim = Integer.parseInt("_6000".replaceAll("_", "")); int bIntPrim = Integer.parseInt("-6000");

Tenga en cuenta aquí en la línea 3 que se permiten números negativos , utilizando el carácter de guión como signo menos.

2.4. Formatos de números específicos de la configuración regional

Veamos un caso especial de números específicos de la configuración regional. En las regiones europeas, una coma puede representar un lugar decimal. Por ejemplo, "4000,1" puede representar el número decimal "4000,1".

De forma predeterminada, obtendremos NumberFormatException al intentar analizar un valor que contenga una coma:

double aDoublePrim = Double.parseDouble("4000,1");

Necesitamos permitir comas y evitar la excepción en este caso. Para que esto sea posible, Java necesita entender la coma aquí como decimal.

Podemos permitir comas para la región europea y evitar la excepción utilizando NumberFormat .

Veámoslo en acción usando el Locale para Francia como ejemplo:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE); Number parsedNumber = numberFormat.parse("4000,1"); assertEquals(4000.1, parsedNumber.doubleValue()); assertEquals(4000, parsedNumber.intValue()); 

3. Mejores prácticas

Hablemos de algunas buenas prácticas que pueden ayudarnos a lidiar con NumberFormatException :

  1. Don't try to convert alphabetic or special characters into numbers – the Java Number API cannot do that.
  2. We may want to validate an input string using regular expressions and throw the exception for the invalid characters.
  3. We can sanitize input against foreseeable known issues with methods like trim() and replaceAll().
  4. In some cases, special characters in input may be valid. So, we do special processing for that, using NumberFormat, for example, which supports numerous formats.

4. Conclusion

In this tutorial, we discussed NumberFormatException in Java and what causes it. Understanding this exception can help us to create more robust applications.

Además, aprendimos estrategias para evitar la excepción con algunas cadenas de entrada no válidas.

Finalmente, vimos algunas mejores prácticas para tratar con NumberFormatException .

Como de costumbre, el código fuente utilizado en los ejemplos se puede encontrar en GitHub.