Avez-vous remarqué java.lang.NullPointerException (NPE) ? 8 meilleures pratiques pour éviter l'exécution NPE en Java
Publié: 2020-10-07
Évitez l'exception Null Pointer en Java et les conseils et meilleures pratiques Java pour éviter l'exception NullPointerException en Java.
En tant que développeur Java, je suis sûr que vous avez dû faire face à une exception de pointeur nul (NPE) à partir du 1er jour. Dans la plupart des cas, l'exception NPE affiche une trace de pile claire qui indique la cause première de la même chose, mais dans le cas d'une grande application au niveau de l'entreprise dans laquelle vous avez des centaines de classes, il devient un cauchemar de découvrir la cause première réelle.
Qu'est-ce que l'exception de pointeur nul (NPE) ?
NullPointerException (NPE)
est une exception qui se produit lorsque vous essayez d'utiliser une référence qui ne pointe vers aucun emplacement en mémoire (null) comme si elle faisait référence à un objet.
Appeler une méthode sur une référence null
ou essayer d'accéder à un champ d'une référence nulle déclenchera un NPE. C'est la cause la plus fréquente.
Selon JavaDoc, voici les principales causes de NPE :
- Lancer
null
comme s'il s'agissait d'une valeurThrowable
. - Appel de la méthode d'instance d'un objet
null
. - Accéder ou modifier le champ d'un objet
null
. - Prendre la longueur de
null
comme s'il s'agissait d'un tableau. - Accéder ou modifier les emplacements de
null
comme s'il s'agissait d'un tableau.
Maintenant, la vraie question est de savoir comment éviter java.lang.NullPointerException lors de l'exécution ? Dans ce didacticiel, nous examinerons quelques exemples qui créent NPE au moment de l'exécution et les étapes que nous devons effectuer pour résoudre ce problème.
Créons NPE au moment de l'exécution en premier. Jetez un oeil à l'exemple ci-dessous CrunchifyNullPointerExceptionTips.java
Nous allons créer NPE de 3 manières différentes
- NPE sera lancé si vous essayez d'accéder à un objet nul
- NPE sera lancé si vous essayez de convertir une chaîne nulle
- NPE sera lancé si vous essayez d'accéder à un objet nul lors de l'initialisation de la classe
Créer la classe CrunchifyNullPointerExceptionTips.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
package crunchify . com . tutorial ; /** * @author Crunchify.com * Have you Noticed java.lang.NullPointerException (NPE)? 8 Best practices to avoid runtime NPE in Java */ public class CrunchifyNullPointerExceptionTips { public static void main ( String [ ] args ) { try { // Example 1: NPE will be thrown if you are trying to access null Object CrunchifyNPE1 ( ) ; } catch ( NullPointerException crunchifyNPE1 ) { System . out . println ( "Exception in CrunchifyNPE1()" ) ; crunchifyNPE1 . printStackTrace ( ) ; } try { // Example 2: NPE will be thrown if you are trying to convert null String CrunchifyNPE2 ( ) ; } catch ( NullPointerException crunchifyNPE2 ) { System . out . println ( "\nException in CrunchifyNPE2()" ) ; // printStackTrace(): Prints this throwable and its backtrace to the standard error stream. // This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err. // The first line of output contains the result of the toString() method for this object. // Remaining lines represent data previously recorded by the method fillInStackTrace(). crunchifyNPE2 . printStackTrace ( ) ; } try { // Example 3: NPE will be thrown if you are trying to access null Object during Class Initialization CrunchifyNPETest npe = new CrunchifyNPETest ( ) ; npe . getName ( ) ; // NullPointerException: Thrown when an application attempts to use null in a case where an object is required. These include: // - Calling the instance method of a null object. // - Accessing or modifying the field of a null object. // - Taking the length of null as if it were an array. // - Accessing or modifying the slots of null as if it were an array. // - Throwing null as if it were a Throwable value. } catch ( NullPointerException crunchifyNPE3 ) { System . out . println ( "\n Exception in CrunchifyNPETest()" ) ; crunchifyNPE3 . printStackTrace ( ) ; } } private static void CrunchifyNPE1 ( ) { Object crunchifyObj = null ; // hasCode(): Returns a hash code value for the object. // This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. crunchifyObj . hashCode ( ) ; } private static void CrunchifyNPE2 ( ) { String crunchifyString ; crunchifyString = "https://crunchify.com" ; // The line 40 declares a variable named "crunchifyString", but, it does not contain a primitive value. Instead it contains a pointer (because the type is String // which is a reference type). Since you did not say as yet what to point to Java sets it to null, meaning "I am pointing at nothing". // In line 41, the new keyword is used to instantiate (or create) an object of type String and the pointer variable "crunchifyString" is assigned this // object. You can now reference the object using the dereferencing operator . (a dot). System . out . println ( "\nvalue: " + crunchifyString . toString ( ) + ", length: " + crunchifyString . length ( ) ) ; System . out . println ( "No NPE exception on line 51" ) ; // Now Let's create NPE String crunchifyString2 = null ; System . out . println ( crunchifyString2 . toString ( ) ) ; } } class CrunchifyNPETest { private String crunchifyName ; public void setName ( String name ) { this . crunchifyName = name ; } public void getName ( ) { printName ( crunchifyName ) ; } private void printName ( String s ) { System . out . println ( s + " (" + s . length ( ) + ")" ) ; } } |
Résultat:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Exception in CrunchifyNPE1 ( ) java . lang . NullPointerException : Cannot invoke "Object.hashCode()" because "crunchifyObj" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE1 ( CrunchifyNullPointerExceptionTips . java : 59 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 14 ) value : https : //crunchify.com, length: 21 No NPE exception on line 51 Exception in CrunchifyNPE2 ( ) Exception in CrunchifyNPETest ( ) java . lang . NullPointerException : Cannot invoke "String.toString()" because "crunchifyString2" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE2 ( CrunchifyNullPointerExceptionTips . java : 75 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 23 ) java . lang . NullPointerException : Cannot invoke "String.length()" because "s" is null at crunchify . com . tutorial . CrunchifyNPETest . printName ( CrunchifyNullPointerExceptionTips . java : 92 ) at crunchify . com . tutorial . CrunchifyNPETest . getName ( CrunchifyNullPointerExceptionTips . java : 88 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 38 ) Process finished with exit code 0 |
Eh bien, il existe quelques trucs et astuces que nous pourrions utiliser pour éviter NullPointerException lors de l'exécution. Nous allons jeter un coup d'oeil.

Astuce 1 :
Eclipse / IntelliJ IDE essaiera d'afficher NPE dans l'espace de travail. Corrigez votre code pendant le développement uniquement.

Astuce 2 :
Ajouter crunchifyI
sNullorEmpty
()
avant une opération sur l'objet. Ajoutez ceci à CrunchifyNullPointerExceptionTips.java
1 2 3 4 5 6 7 8 |
public static boolean crunchifyIsNullOrEmpty ( String crunchifyStr ) { if ( crunchifyStr == null ) return true ; else if ( crunchifyStr . trim ( ) . equals ( "" ) ) return true ; else return false ; } |
Dans le programme Java ci-dessus, les lignes 55 et 56 seront remplacées par ceci.
1 2 3 4 5 6 |
String crunchifyString2 = null ; if ( ! crunchifyIsNullOrEmpty ( crunchifyString2 ) ) { System . out . println ( crunchifyString2 . toString ( ) ) ; } else { System . out . println ( "crunchifyString2 is null" ) ; } |
Astuce 3 :
Vérifiez si String est null
ou vide après l'opération trim().
1 2 3 |
public static boolean isNullOrEmptyAfterTrim ( String crunchifyStr ) { return ( crunchifyStr == null | | crunchifyStr . trim ( ) . length ( ) == 0 ) ; } |
Astuce 4 :
Utilisez toujours le Try Catch block
afin d'empêcher un processus d'exécution ininterrompu.
1 2 3 4 5 |
try { CrunchifyNPE1 ( ) ; } catch ( NullPointerException npe ) { System . out . println ( "Exception in CrunchifyNPE1()" + npe ) ; } |
Astuce 5 :
Collections.emptyList()
est préféré en raison d'une meilleure gestion des génériques.
Astuce 6 :
Utiliser Java Assertions
Une assertion est une déclaration qui vous permet de tester vos hypothèses sur votre code. Par exemple, si vous écrivez une méthode qui renvoie le nom dans le système, vous pouvez affirmer que le retour otherName si String est nul.
L'utilisation de base des assertions serait:
1 2 3 4 5 6 7 8 |
assert < Expression > ; // or another usage is assert < Expression1 > : < Expression2 > ; // in our program add line below. private void printName ( String s ) { assert ( s ! = null ) : "Name must be not null" ; System . out . println ( s + " (" + s . length ( ) + ")" ) ; } |
Mais il y a un hic : Assertion n'est pas disponible dans l'environnement de production et nous ne devrions pas utiliser Assertion avec une logique métier.
Astuce 7 :
Essayez d'utiliser les contrôles containsKey()
, containsValue()
, contains()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com . crunchify . tutorial ; import java . util . * ; /** * @author Crunchify.com * */ public class CrunchifyContainsKeyExample { public static void main ( String args [ ] ) { HashMap < Integer , String > crunchifyMap = new HashMap < Integer , String > ( ) ; // populate hash map crunchifyMap . put ( 1 , "Crunchify" ) ; crunchifyMap . put ( 2 , "wordpress" ) ; crunchifyMap . put ( 3 , "java tutorials" ) ; // check existence of key 4 if ( crunchifyMap . containsKey ( 4 ) ) { System . out . println ( "Check if key 2 exists: " + crunchifyMap . get ( 4 ) ) ; } else { System . out . println ( "NPE for value 4 avoided" ) ; } } } |
Astuce 8 :
En conclusion, c'est toujours une bonne pratique de prendre soin de NPE pendant le développement plutôt que de déboguer en production au moment de l'exécution. Il existe de nombreux autres trucs et astuces disponibles en utilisant Spring Framework Annotation, Factory Pattern
, Null Object Pattern etc. Mais je vais couper court maintenant.
Publiera probablement un nouveau tutoriel dans une semaine sur celui-ci. Restez à l'écoute.
Voulez-vous ajouter quelque chose à ce didacticiel OU avez-vous trouvé un problème, veuillez intervenir et fournir vos commentaires.