Compruebe si nulo booleano es verdadero resultados en excepción


169

Tengo el siguiente código:

Boolean bool = null;

try 
{
    if (bool)
    {
        //DoSomething
    }                   
} 
catch (Exception e) 
{
    System.out.println(e.getMessage());             
}

¿Por qué mi chequeo en la variable booleana "bool" resulta en una excepción? ¿No debería simplemente saltar más allá de la declaración if cuando "ve" que no es cierto? Cuando elimino la declaración if o verifico si NO es nula, la excepción desaparece.


3
Las respuestas anteriores sobre unboxing de objetos son correctas. Sin embargo, por razones de integridad, también puede cambiar su código para usar el primitivo "booleano" en lugar del contenedor de objetos "booleano". También debe actualizarse sobre la diferencia entre un primitivo y un objeto.
— Marvo

Mientras tanto ... if (bool == Boolean.TRUE)evalúa falso sin generar una excepción. No estoy seguro si esto fue intencional en el caso que acabo de encontrar.
— simon.watts

2
@ simon.watts que sería falso por boolser nullOR si Booleanse construyera explícitamente (y no como referencia Boolean.TRUE). Entonces no recomendado; a diferencia de if (Boolean.TRUE.equals(bool))lo que funcionaría como se esperaba, incluido el manejo seguro del nullvalor.
— StaxMan

Respuestas:


171

Cuando tienes un booleanpuede ser trueo false. Sin embargo, cuando tienes un Booleanpuede ser cualquiera Boolean.TRUE, Boolean.FALSEo nullcomo cualquier otro objeto.

En su caso particular, su instrucción Booleanis nully la ifdesencadena una conversión implícita a la booleanque produce el NullPointerException. Es posible que necesite en su lugar:

if(bool != null && bool) { ... }

23
Técnicamente, a Booleanpuede ser cualquier número de instancias verdaderas, no solo Boolean.TRUE. Por ejemplo new Boolean(true).
— Steve Kuo

1
Me cuesta entender por qué if (myBoolean)(dónde myBooleanestá Boolean) no genera un error del compilador o al menos una advertencia. Este es un problema seguro.
— Josh M.

1
@JoshM. Esto se debe a que Java realiza el encajonamiento y desempaquetado de envoltorios: docs.oracle.com/javase/tutorial/java/data/autoboxing.html
— Vinicius

3
@Vinicius seguro, pero el compilador debe hacer lo nulo por nosotros en este caso, al menos a través de una advertencia del compilador.
— Josh M.

2
@JoshM. No puedo estar más de acuerdo :)
— Vinicius

402

Si no le gustan los cheques nulos adicionales:

if (Boolean.TRUE.equals(value)) {...}

1
@AvrDragon: ¿se requiere igual? Operador == funciona aquí ya que el booleano solo tiene dos valores
— Atul el

77
@ Atul Sí, se requiere igual aquí. Porque (new Boolean (true) == new Boolean (true)) es ... falso. Motivo: Boolean es solo una clase y puede tener múltiples instancias como cualquier otra clase en Java.
— AvrDragon

35
Sí, eso es una lástima, el constructor debe ser privada por lo que ha asegurado que se trata de un twingleton ...
— FORTRAN

15
@fortran +1 para "twingleton".
— Bennett McElwee

1
No tiene absolutamente ningún sentido usar Apache BooleanUtils sobre este idioma.
— StaxMan

82

Utilice los Apache BooleanUtils .

(Si el rendimiento máximo es la prioridad más importante en su proyecto, busque una de las otras respuestas para una solución nativa que no requiera incluir una biblioteca externa).

No reinventes la rueda. Aproveche lo que ya se ha construido y use isTrue():

BooleanUtils.isTrue( bool );

Comprueba si un Booleanvalor es verdadero, manejándolo nullregresando false.

Si no está limitado a las bibliotecas que está "permitido" incluir, hay un montón de excelentes funciones auxiliares para todo tipo de casos de uso, incluidos Booleansy Strings. Le sugiero que lea detenidamente las diversas bibliotecas de Apache y vea lo que ya ofrecen.


59
Reinventar la rueda no parece tan malo cuando la alternativa es usar una biblioteca externa para algo tan básico como esto.
— Paul Manta

3
@PaulManta Estoy de acuerdo si esta es la única cosa que le nunca utiliza en las bibliotecas Apache Utils, pero la idea sugerida es la de "hojear" las bibliotecas exponerse a otras funciones útiles.
— Joshua Pinter

1
Hay una penalización de rendimiento por usar estas bibliotecas. Entonces, para cosas tan básicas que son parte del lenguaje, no debe usar bibliotecas.
— ACV

66
Esa biblioteca está reinventando la rueda. Intento evitar tales bibliotecas tanto como sea posible.
— mschonaker

3
@mschonaker Si Apache BooleanUtils está reinventando la rueda, ¿cuál es la rueda original ? La idea es evitar crear un montón de funciones auxiliares que imiten lo que ya se ha hecho en bibliotecas como esta. También uso toStringYesNode esta biblioteca en todas mis aplicaciones.
— Joshua Pinter

13

Booleantipos pueden ser null. Debe hacer una nullcomprobación tal como la configuró null.

if (bool != null && bool)
{
  //DoSomething
}                   

3
¿Qué hay de malo en esta respuesta? No es la comprobación del bool lo que arrojaría la excepción. Votos negativos innecesarios.
— dodexahedron

2
Estoy de acuerdo en que es una respuesta perfectamente razonable. Sin embargo, podría deshacerse del manejo de excepciones.
— Marvo

14
La entrega de excepciones es innecesaria, y además se está haciendo de una manera que es un mal ejemplo para los principiantes. Esto merece un voto negativo, OMI. (Sí ... Sé que proviene del código de ejemplo, pero repetirlo en la Respuesta parece respaldarlo)
— Stephen C

1
¿Cuál es el camino CORRECTO entonces? No veo tu respuesta aquí.
— Marvo

55
La forma correcta es la de arriba ... sin manejo de excepciones. Además, el manejo de excepciones es demasiado general y no se recomienda.
— vellvisher

8

O con el poder de Java 8 Opcional, también puedes hacer ese truco:

Optional.ofNullable(boolValue).orElse(false)

:)


5

Boolean es la clase de contenedor de objetos para el booleano primitivo. Esta clase, como cualquier clase, puede ser nula. Por razones de rendimiento y memoria, siempre es mejor usar el primitivo.

Las clases de contenedor en la API de Java tienen dos propósitos principales:

  1. Proporcionar un mecanismo para "ajustar" los valores primitivos en un objeto de modo que las primitivas puedan incluirse en actividades reservadas para objetos, como agregarse a Colecciones o devolverse desde un método con un valor de retorno de objeto.
  2. Proporcionar una variedad de funciones de utilidad para primitivas. La mayoría de estas funciones están relacionadas con varias conversiones: conversión de primitivas hacia y desde objetos String, y conversión de primitivas y objetos String hacia y desde diferentes bases (o radix), como binarias, octales y hexadecimales.

http://en.wikipedia.org/wiki/Primitive_wrapper_class


0

Como su variable bool apunta a un valor nulo, siempre obtendrá una NullPointerException, primero debe inicializar la variable en algún lugar con un valor no nulo y luego modificarla.


1
Si fuera solo eso, el catchbloque manejaría la NullPointerException. El problema aquí es que el OP intenta desempaquetar una referencia nula en una primitiva.
— Mike Adler

"siempre lo harás" : no siempre, excepto el código simplificado de muestra que no hace nada entre inicializar la variable nully luego probarla. Presumiblemente, el código real no sería tan simple o toda la ifprueba podría eliminarse.
— nnnnnn
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.