Comprendre la NumberFormatException en Java

1. Introduction

Java lève NumberFormatException - une exception non vérifiée - lorsqu'il ne peut pas convertir une chaîne en un type de nombre.

Puisqu'il n'est pas coché, Java ne nous oblige pas à le gérer ou à le déclarer.

Dans ce rapide didacticiel, nous allons décrire et démontrer les causes de NumberFormatException en Java et comment l'éviter ou y faire face .

2. Causes de NumberFormatException

Il existe différents problèmes qui provoquent NumberFormatException . Par exemple, certains constructeurs et méthodes en Java lèvent cette exception.

Nous aborderons la plupart d'entre eux dans les sections ci-dessous.

2.1. Données non numériques transmises au constructeur

Examinons une tentative de construction d'un objet Integer ou Double avec des données non numériques.

Ces deux instructions lèveront NumberFormatException :

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

Voyons la trace de pile que nous avons obtenue lorsque nous avons passé l'entrée invalide «un» au constructeur Integer à la ligne 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)

Il a jeté NumberFormatException . Le constructeur Integer a échoué en essayant de comprendre l'entrée à l'aide de parseInt () en interne.

L'API Java Number n'analyse pas les mots en nombres, nous pouvons donc corriger le code en le changeant simplement en une valeur attendue:

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

2.2. Analyse des chaînes contenant des données non numériques

Semblable à la prise en charge par Java de l'analyse dans le constructeur, nous avons des méthodes d'analyse dédiées telles que par seInt (), parseDouble (), valueOf () et decode () .

Si nous essayons de faire les mêmes types de conversion avec ceux-ci:

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

Ensuite, nous verrons le même genre de comportement erroné.

Et nous pouvons les corriger de la même manière:

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

2.3. Passer des chaînes avec des caractères étrangers

Ou, si nous essayons de convertir une chaîne en un nombre avec des données superflues en entrée, comme des espaces ou des caractères spéciaux:

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

Ensuite, nous aurons le même problème qu'avant.

Nous pourrions les corriger avec un peu de manipulation de chaîne:

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

Notez ici à la ligne 3 que les nombres négatifs sont autorisés , en utilisant le trait d'union comme signe moins.

2.4. Formats de nombres spécifiques aux paramètres régionaux

Voyons un cas particulier de nombres spécifiques aux paramètres régionaux. Dans les régions européennes, une virgule peut représenter une décimale. Par exemple, «4000,1» peut représenter le nombre décimal «4000,1».

Par défaut, nous obtiendrons NumberFormatException en essayant d'analyser une valeur contenant une virgule:

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

Nous devons autoriser les virgules et éviter l'exception dans ce cas. Pour rendre cela possible, Java doit comprendre la virgule ici comme une décimale.

Nous pouvons autoriser les virgules pour la région européenne et éviter l'exception en utilisant NumberFormat .

Voyons cela en action en utilisant le Locale pour la France comme exemple:

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

3. Meilleures pratiques

Parlons de quelques bonnes pratiques qui peuvent nous aider à gérer NumberFormatException :

  1. N'essayez pas de convertir des caractères alphabétiques ou spéciaux en nombres - l'API Java Number ne peut pas le faire.
  2. Nous pouvons vouloir valider une chaîne d'entrée à l'aide d'expressions régulières et lever l'exception pour les caractères invalides .
  3. Nous pouvons nettoyer l'entrée contre les problèmes connus prévisibles avec des méthodes comme trim () et replaceAll () .
  4. Dans certains cas, les caractères spéciaux en entrée peuvent être valides. Donc, nous faisons un traitement spécial pour cela, en utilisant NumberFormat, par exemple, qui prend en charge de nombreux formats.

4. Conclusion

Dans ce didacticiel, nous avons discuté de NumberFormatException en Java et de ses causes. Comprendre cette exception peut nous aider à créer des applications plus robustes.

De plus, nous avons appris des stratégies pour éviter l'exception avec certaines chaînes d'entrée invalides.

Enfin, nous avons vu quelques bonnes pratiques pour gérer NumberFormatException .

Comme d'habitude, le code source utilisé dans les exemples se trouve à l'adresse over sur GitHub.