100 votes

Pourquoi int num = Integer.getInteger("123") lance-t-il NullPointerException ?

Le code suivant génère un NPE pour moi :

int num = Integer.getInteger("123");

mon compilateur invoque-t-il getInteger sur null puisqu'il est statique ? cela n'a aucun sens !

Quelqu'un peut-il expliquer ce qui se passe ?

Merci.

207voto

polygenelubricants Points 136838

La vue d'ensemble

Il y a deux problèmes en jeu ici :

  • Integer getInteger(String) ne fait pas ce que vous pensez qu'il fait
    • Il retourne null dans ce cas
  • l'affectation de Integer a int provoque un déblocage automatique
    • Depuis le Integer es null , NullPointerException est jeté

Pour analyser (String) "123" a (int) 123 vous pouvez utiliser par exemple int Integer.parseInt(String) .

Références

Integer Références API


Sur Integer.getInteger

Voici ce que la documentation a à dire sur ce que fait cette méthode :

public static Integer getInteger(String nm) : Détermine la valeur entière de la propriété système portant le nom spécifié. S'il n'y a pas de propriété avec le nom spécifié, si le nom spécifié est vide ou s'il n'y a pas de propriété avec le nom spécifié. null ou si la propriété n'a pas le format numérique correct, alors null est renvoyé.

En d'autres termes, cette méthode n'a rien à voir avec l'analyse syntaxique d'un fichier de type String à un int/Integer mais il s'agit plutôt d'une question de System.getProperty méthode.

Il est vrai que cela peut être une surprise. Il est malheureux que la bibliothèque réserve de telles surprises, mais cela vous apprend une leçon précieuse : consultez toujours la documentation pour confirmer ce que fait une méthode.

Par coïncidence, une variation de ce problème a été présenté dans Le retour des casse-têtes : Schlock et Awe (TS-5186) , la présentation de Josh Bloch et Neal Gafter lors de la session technique JavaOne 2009. Voici la diapositive de conclusion :

La morale

  • Des méthodes étranges et terribles se cachent dans les bibliothèques
    • Certains ont des noms à consonance inoffensive
  • Si votre code se comporte mal
    • Assurez-vous que vous appelez les bonnes méthodes
    • Lire la documentation de la bibliothèque
  • Pour les concepteurs d'API
    • Ne pas violer le principe du moindre étonnement
    • Ne pas violer la hiérarchie d'abstraction
    • N'utilisez pas de noms similaires pour des comportements très différents.

Pour être complet, il y a aussi ces méthodes qui sont analogues à Integer.getInteger :

Questions connexes


Sur l'autounboxing

L'autre question, bien sûr, c'est de savoir comment les NullPointerException est jeté. Pour nous concentrer sur ce problème, nous pouvons simplifier l'extrait comme suit :

Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!

Voici une citation de Effective Java 2nd Edition, Item 49 : Prefer primitive types to boxed primitives :

En résumé, utilisez les primitives de préférence aux primitives encadrées chaque fois que vous avez le choix. Les types primitifs sont plus simples et plus rapides. Si vous devez utiliser des primitives encadrées, faites attention ! L'auto-boxage réduit la verbosité, mais pas le danger, de l'utilisation de primitives encadrées. Lorsque votre programme compare deux primitives encadrées avec l'élément == opérateur, il effectue une comparaison d'identité, ce qui n'est certainement pas ce que vous voulez. Lorsque votre programme effectue des calculs de type mixte impliquant des primitives encadrées et non encadrées, il effectue un unboxing, et lorsque votre programme effectue un unboxing, il peut lancer NullPointerException . Enfin, lorsque votre programme met en boîte des valeurs primitives, cela peut entraîner des créations d'objets coûteuses et inutiles.

Il y a des endroits où vous n'avez pas d'autre choix que d'utiliser des primitives encadrées, par exemple les génériques, mais autrement vous devriez sérieusement considérer si une décision d'utiliser des primitives encadrées est justifiée.

Questions connexes

16voto

Kieren Johnstone Points 19499

De http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :

getInteger "Détermine la valeur entière de la propriété système portant le nom spécifié.

Tu veux ça :

Integer.parseInt("123")

6voto

Sonal Patil Points 143

Veuillez vérifier la documentation de la méthode getInteger() . Dans cette méthode, le String Le paramètre est une propriété système qui détermine la valeur entière de la propriété système portant le nom spécifié. "123" n'est pas le nom d'une propriété système, comme nous l'avons vu. aquí . Si vous voulez convertir cette chaîne en int puis utiliser la méthode suivante int num = Integer.parseInt("123") .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X