Boolean.valueOf () produit parfois une exception NullPointerException

J’ai ce code:

package tests; import java.util.Hashtable; public class Tests { public static void main(Ssortingng[] args) { Hashtable modifiedItems = new Hashtable(); System.out.println("TEST 1"); System.out.println(modifiedItems.get("item1")); // Prints null System.out.println("TEST 2"); System.out.println(modifiedItems.get("item1") == null); // Prints true System.out.println("TEST 3"); System.out.println(Boolean.valueOf(null)); // Prints false System.out.println("TEST 4"); System.out.println(Boolean.valueOf(modifiedItems.get("item1"))); // Produces NullPointerException System.out.println("FINISHED!"); // Never executed } } 

Mon problème est que je ne comprends pas pourquoi le test 3 fonctionne correctement (il imprime false et ne produit pas de NullPointerException ) tandis que le test 4 lance une NullPointerException . Comme vous pouvez le voir dans les tests 1 et 2 , null et modifiedItems.get("item1") sont égaux et null .

Le comportement est le même en Java 7 et 8.

Vous devez regarder attentivement quelle surcharge est invoquée:

  • Boolean.valueOf(null) appelle Boolean.valueOf(Ssortingng) . Cela ne lance pas un NPE même s’il est fourni avec un paramètre null.
  • Boolean.valueOf(modifiedItems.get("item1")) appelle Boolean.valueOf(boolean) , car les valeurs de modifiedItems sont de type Boolean , ce qui nécessite une conversion unboxing. Puisque modifiedItems.get("item1") est null , c’est le unboxing de cette valeur – pas le Boolean.valueOf(...) – qui lance le NPE.

Les règles pour déterminer quelle surcharge est invoquée sont très poilues , mais elles vont grossièrement comme ceci:

  • Dans une première passe, une correspondance de méthode est recherchée sans autoriser la boxe / unboxing (ni les méthodes d’arity variables).

    • Étant donné que null est une valeur acceptable pour une Ssortingng mais pas une valeur boolean , Boolean.valueOf(null) correspond à Boolean.valueOf(Ssortingng) dans cette passe;
    • Boolean n’est pas acceptable pour Boolean.valueOf(Ssortingng) ou Boolean.valueOf(boolean) , donc aucune méthode n’est mise en correspondance dans cette passe pour Boolean.valueOf(modifiedItems.get("item1")) .
  • Dans une seconde passe, une correspondance de méthode est recherchée, permettant la boxe / unboxing (mais toujours pas les méthodes d’arity variables).

    • Un Boolean peut être unboxed à boolean , donc Boolean.valueOf(boolean) correspond à Boolean.valueOf(modifiedItems.get("item1")) dans cette passe; mais le compilateur doit insérer une conversion unboxing pour l’invoquer: Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • (Il existe une troisième passe autorisant les méthodes d’arity variables, mais ce n’est pas pertinent ici, car les deux premières passes correspondent à ces cas)

Puisque modifiedItems.get renvoie un Boolean (qui ne peut pas être converti en une Ssortingng ), la signature à utiliser est Boolean.valueOf(boolean) , où le Boolean est envoyé à un boolean primitif. Une fois la valeur null renvoyée, la boîte d’envoi échoue avec une exception NullPointerException .

Signature de la méthode

La méthode Boolean.valueOf(...) a deux signatures:

  1. public static Boolean valueOf(boolean b)
  2. public static Boolean valueOf(Ssortingng s)

Votre valeur modifiedItems est Boolean . Vous ne pouvez pas convertir Boolean en Ssortingng , par conséquent la première signature sera choisie

Unboxing booléen

Dans votre déclaration

 Boolean.valueOf(modifiedItems.get("item1")) 

qui peut être lu comme

 Boolean.valueOf(modifiedItems.get("item1").booleanValue()) 

Cependant, modifiedItems.get("item1") renvoie null donc vous aurez essentiellement

 null.booleanValue() 

ce qui conduit évidemment à une NullPointerException

Comme Andy a déjà très bien décrit la raison de NullPointerException :

ce qui est dû à la désinsertion booléenne:

 Boolean.valueOf(modifiedItems.get("item1")) 

se convertir en:

 Boolean.valueOf(modifiedItems.get("item1").booleanValue()) 

à l’exécution, puis il lance NullPointerException si modifiedItems.get("item1") est nul.

Maintenant, je voudrais append un autre point ici: la suppression des boîtes suivantes dans leurs primitives respectives peut aussi produire une exception NullPointerException si leurs objects retournés correspondants sont nuls.

  1. byte – Byte
  2. char – Caractère
  3. float – Float
  4. int – Entier
  5. long – long
  6. court – court
  7. double double

Voici le code:

  Hashtable modifiedItems1 = new Hashtable(); System.out.println(Boolean.valueOf(modifiedItems1.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems2 = new Hashtable(); System.out.println(Byte.valueOf(modifiedItems2.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems3 = new Hashtable(); System.out.println(Character.valueOf(modifiedItems3.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems4 = new Hashtable(); System.out.println(Float.valueOf(modifiedItems4.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems5 = new Hashtable(); System.out.println(Integer.valueOf(modifiedItems5.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems6 = new Hashtable(); System.out.println(Long.valueOf(modifiedItems6.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems7 = new Hashtable(); System.out.println(Short.valueOf(modifiedItems7.get("item1")));//Exception in thread "main" java.lang.NullPointerException Hashtable modifiedItems8 = new Hashtable(); System.out.println(Double.valueOf(modifiedItems8.get("item1")));//Exception in thread "main" java.lang.NullPointerException 

Une façon de le comprendre est que lorsque Boolean.valueOf(null) est invoqué, java est précisément invité à évaluer null.

Cependant, lorsque Boolean.valueOf(modifiedItems.get("item1")) est invoqué, java est invité à obtenir une valeur à partir de la table de hachage de type object booléen, mais il ne trouve pas le type booléen trouvé à la place ( null) même si elle attendait une valeur booléenne. L’exception NullPointerException est levée car les créateurs de cette partie de Java ont décidé que cette situation est une instance de quelque chose dans le programme qui tourne mal et qui nécessite l’attention du programmeur. (Quelque chose d’inattendu s’est produit.)

Dans ce cas, il y a plus de différence entre déclarer volontairement que le null est présent et java trouver une référence manquante à un object (null) où un object devait être trouvé.

Voir plus d’informations sur NullPointerException dans cette réponse: https://stackoverflow.com/a/25721181/4425643