traducir sale porque pointer method cause catch java nullpointerexception boolean

java - sale - nullpointerexception processing



Boolean.valueOf() produce NullPointerException a veces (5)

Firma del método

El método Boolean.valueOf(...) tiene dos firmas:

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

Su valor modifiedItems Artículos es Boolean . No puede convertir Boolean a String por lo tanto, se elegirá la primera firma

Unboxing booleano

En su estado de cuenta

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

que se puede leer como

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

Sin embargo, modifiedItems.get("item1") devuelve null por lo que básicamente tendrá

null.booleanValue()

que obviamente conduce a una NullPointerException

Tengo este codigo:

package tests; import java.util.Hashtable; public class Tests { public static void main(String[] args) { Hashtable<String, Boolean> modifiedItems = new Hashtable<String, Boolean>(); 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 } }

Mi problema es que no entiendo por qué la Prueba 3 funciona bien (imprime false y no produce NullPointerException ) mientras que la Prueba 4 arroja una NullPointerException . Como puede ver en las pruebas 1 y 2 , null y modifiedItems.get("item1") son iguales y null .

El comportamiento es el mismo en Java 7 y 8.


Como Andy ya describió muy bien la razón de NullPointerException :

que se debe al desempaquetado booleano:

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

convertirse en:

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

en tiempo de ejecución y luego arroja NullPointerException si modifiedItems.get("item1") es nulo.

Ahora me gustaría agregar un punto más aquí que el desempaquetado de las siguientes clases a sus respectivas primitivas también puede producir la excepción NullPointerException si sus objetos devueltos correspondientes son nulos.

  1. byte - Byte
  2. char - Personaje
  3. flotador - Flotador
  4. int - Entero
  5. largo largo
  6. corto - Corto
  7. doble doble

Aquí está el código:

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


Dado que modifiedItems.get devuelve un Boolean (que no se puede convertir en una String ), la firma que se utilizaría es Boolean.valueOf(boolean) , donde el Boolean se convierte en un boolean primitivo. Una vez que se devuelve null allí, el buzón de salida falla con una excepción NullPointerException .


Debe observar cuidadosamente qué sobrecarga se invoca:

  • Boolean.valueOf(null) invoca a Boolean.valueOf(String) . Esto no arroja un NPE incluso si se suministra con un parámetro nulo.
  • Boolean.valueOf(modifiedItems.get("item1")) está invocando Boolean.valueOf(boolean) , porque los valores de modifiedItems son de tipo Boolean , lo que requiere una conversión de unboxing. Dado que modifiedItems.get("item1") es null , es el desempaquetado de ese valor, no el Boolean.valueOf(...) , lo que arroja el NPE.

Las reglas para determinar qué sobrecarga se invoca son bastante complicadas , pero a grandes rasgos son así:

  • En una primera pasada, se busca una coincidencia de métodos sin permitir el encajonamiento / desempaquetado (ni los métodos de aridad variable).

    • Debido a que null es un valor aceptable para un String pero no boolean , Boolean.valueOf(null) se corresponde con Boolean.valueOf(String) en este paso;
    • Boolean no es aceptable para Boolean.valueOf(String) o Boolean.valueOf(boolean) , por lo que no se Boolean.valueOf(modifiedItems.get("item1")) ningún método en este pase para Boolean.valueOf(modifiedItems.get("item1")) .
  • En una segunda pasada, se busca una coincidencia de métodos, lo que permite el boxeo / unboxing (pero aún no los métodos de arity variables).

    • Un Boolean se puede desempaquetar en boolean , por lo que Boolean.valueOf(boolean) se corresponde con Boolean.valueOf(modifiedItems.get("item1")) en este pase; pero el compilador debe insertar una conversión de unboxing para invocarla: Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • (Hay un tercer paso que permite métodos de arity variables, pero eso no es relevante aquí, ya que los dos primeros pasos coincidieron con estos casos)


Una forma de entenderlo es cuando se Boolean.valueOf(null) , precisamente se le dice a java que evalúe null.

Sin embargo, cuando se Boolean.valueOf(modifiedItems.get("item1")) , se le dice a java que obtenga un valor de HashTable del tipo de objeto Boolean, pero no encuentra el tipo Boolean sino que encuentra un callejón sin salida ( nulo) a pesar de que esperaba booleano. La excepción NullPointerException se produce porque los creadores de esta parte de Java decidieron que esta situación es una instancia de algo en el programa que falla y que necesita la atención del programador. (Algo no intencionado sucedió).

En este caso, es más la diferencia entre declarar deliberadamente que pretendía que el nulo estuviera allí y que Java encuentre una referencia faltante a un objeto (nulo) donde se pretendía encontrar un objeto.

Consulte más información sobre NullPointerException en esta respuesta: https://.com/a/25721181/4425643