web-dev-qa-db-fra.com

Pourquoi int num = Integer.getInteger ("123") lève NullPointerException?

Le code suivant renvoie NullPointerException:

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

Mon compilateur appelle-t-il getInteger sur null car il est statique? Cela n'a aucun sens!

Que ce passe-t-il?

99
user282886

La grande image

Il y a deux problèmes en jeu ici:

  • Integer getInteger(String) ne fait pas ce que vous pensez qu'il fait
    • Il renvoie null dans ce cas
  • l'affectation de Integer à int provoque le décompactage automatique
    • Étant donné que Integer est null, NullPointerException est lancé

Pour analyser (String) "123" En (int) 123, Vous pouvez utiliser par exemple int Integer.parseInt(String).

Les 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 avec le nom spécifié. S'il n'y a aucune propriété avec le nom spécifié, si le nom spécifié est vide ou null, ou si la propriété n'a pas le format numérique correct, alors null est retourné.

En d'autres termes, cette méthode n'a rien à voir avec l'analyse d'une String à une valeur int/Integer, Mais plutôt à System.getProperty méthode.

Certes, cela peut être une surprise. Il est malheureux que la bibliothèque ait des surprises comme celle-ci, mais elle vous enseigne une leçon précieuse: recherchez toujours la documentation pour confirmer ce que fait une méthode.

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

Le moral

  • 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 d'appeler les bonnes méthodes
    • Lire la documentation de la bibliothèque
  • Pour les concepteurs d'API
    • Ne violez pas le principe du moindre étonnement
    • Ne violez pas la hiérarchie d'abstraction
    • N'utilisez pas de noms similaires pour des comportements extrêmement différents

Pour être complet, il existe également ces méthodes qui sont analogues à Integer.getInteger:

Questions connexes


Sur la mise en boîte automatique

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

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

Voici une citation de Effective Java 2nd Edition, Item 49: Préférez les types primitifs aux primitives encadrées:

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'autoboxing 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'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 le déballage et lorsque votre programme effectue le déballage, il peut lancer NullPointerException. Enfin, lorsque votre programme contient 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 génériques, mais sinon vous devriez sérieusement considérer si une décision d'utiliser des primitives encadrées est justifiée.

Questions connexes

205
polygenelubricants

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 avec le nom spécifié.'

Tu veux ça:

Integer.parseInt("123")
16
Kieren Johnstone

Veuillez vérifier la documentation de la méthode getInteger () . Dans cette méthode, le paramètre String est une propriété système qui détermine la valeur entière de la propriété système avec le nom spécifié. "123" n'est le nom d'aucune propriété système, comme indiqué ici . Si vous souhaitez convertir cette chaîne en int, utilisez la méthode comme int num = Integer.parseInt("123").

6
Sonal Patil