java - sale - nullpointerexception processing
NullPointerException de Boolean (3)
Este es uno para los puristas de java, creo. Recientemente tuve un problema con un método para realizar un análisis personalizado de valores de cadena a un booleano. Una tarea bastante simple, pero por alguna razón el método siguiente arrojaba una NullPointerException en el caso nulo ...
static Boolean parseBoolean(String s)
{
return ("1".equals(s) ? true : ("0".equals(s) ? false : null));
}
El tipo de devolución para el método es booleano, entonces ¿por qué o cómo se puede generar una NullPointerException? Desde la depuración parece que se lanza la excepción en el punto donde la declaración condicional anidada en línea se evalúa como nula y devuelve nulo al condicional externo en línea, pero de nuevo no puedo explicar por qué.
Finalmente, abandoné y reescribí el método de la siguiente manera, que funciona como se esperaba:
static Boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
if ("0".equals(s)) return false;
return null;
}
El siguiente código está a medio camino entre los dos y también funciona como se esperaba:
static Boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
return "0".equals(s) ? false : null;
}
Esto también funciona:
static Boolean parseBoolean(String s)
{
return ("1".equals(s) ? Boolean.TRUE : ("0".equals(s) ? Boolean.FALSE : null));
}
Por lo tanto, la razón por la que obtienes un NPE se debe al autoboxing porque usar boolean
en el operador ternario hace que el resultado de la expresión sea tratado como un boolean
. Y des-boxing de null
causa un NPE.
Interesante pero ninguna respuesta te dice por qué sucede esto en primer lugar.
Esto tiene que ver con la expresión ternaria.
El compilador interpreta nulo como una referencia nula a Boolean, aplica las reglas de autoboxing / unboxing para Boolean (en un nulo) => usted obtiene una NullPointerException en tiempo de ejecución.
¿Mi sugerencia? No devuelva Boolean
, devuelva boolean
y genere una excepción:
static boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
if ("0".equals(s)) return false;
throw new IllegalArgumentException(s + " is not a boolean value.");
}
Adoptar un enfoque como el anterior le ayudará a evitar que haga referencia accidentalmente a un objeto Boolean
nulo.
Vea la excelente respuesta de NilsH para ver por qué su método original arroja una excepción.