¿Cuándo se deben usar los valores nulos de Boolean?

12 minutos de lectura

avatar de usuario
peter.murray.rust

Java boolean permite valores de true y false mientras que Boolean permite true, falsey null. He comenzado a convertir mi booleans a Booleans. Esto puede causar bloqueos en pruebas como

Boolean set = null;
...
if (set) ...

mientras la prueba

if (set != null && set) ...

parece artificial y propenso a errores.

¿Cuándo, si alguna vez, es útil usar Booleans con valores nulos? Si nunca, ¿cuáles son las principales ventajas del objeto envuelto?

ACTUALIZACIÓN: ha habido tantas respuestas valiosas que he resumido algunas en mi propia respuesta. Soy, en el mejor de los casos, un intermedio en Java, así que he tratado de mostrar las cosas que encuentro útiles. Tenga en cuenta que la pregunta está “formulada incorrectamente” (el booleano no puede “tener un valor nulo”), pero la he dejado en caso de que otros tengan la misma idea errónea.

  • A veces, desea un estado no inicializado y la configuración Boolean variable a null ayuda

    – nhahtdh

    25 de junio de 2012 a las 7:50

  • “Siempre” es un poco fuerte que no me atrevo a confirmar, pero esperaría una prueba para null si realmente se usa como un 3er estado.

    – nhahtdh

    25 de junio de 2012 a las 7:54

  • ¿Tiene alguna razón para convertir booleanos a booleanos? Me apegaría al tipo primitivo y lo envolvería solo si hay una buena razón para hacerlo, por ejemplo, cuando necesito pasar una variable por referencia.

    – jpe

    25 de junio de 2012 a las 7:58

  • También es posible que desee comprobar esto: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx

    – biziclop

    25 de junio de 2012 a las 10:26

  • No existe tal cosa como un “valor nulo en un booleano”. Boolean es un objeto, mientras que un boolean es un “escalar”. si un Boolean referencia se establece en nulo, lo que significa que la correspondiente Boolean el objeto no existe. No puedes colocar nada dentro de algo que no existe.

    – Lame caliente

    25 de junio de 2012 a las 18:28

avatar de usuario
JB Nizet

Usar boolean más bien que Boolean cada vez que puedas. Esto evitará muchos NullPointerExceptions y hacer que su código sea más robusto.

Boolean es útil, por ejemplo

  • para almacenar valores booleanos en una colección (Lista, Mapa, etc.)
  • para representar un booleano anulable (procedente de una columna booleana anulable en una base de datos, por ejemplo). El valor nulo podría significar “no sabemos si es verdadero o falso” en este contexto.
  • cada vez que un método necesita un Objeto como argumento, y necesita pasar un valor booleano. Por ejemplo, al usar la reflexión o métodos como MessageFormat.format().

  • Un valor nulo en la base de datos también podría significar “Archivo no encontrado”

    – Carlos Johan

    25 de junio de 2012 a las 12:17


  • Su segunda viñeta es realmente el núcleo de la respuesta correcta a esta pregunta, creo.

    – Niels Brinch

    25 de junio de 2012 a las 15:07

  • Otro uso para Boolean que he tenido es como parámetro de tipo genérico al extender clases genéricas, estrechamente relacionado con el punto 3.

    – Alex

    25 de junio de 2012 a las 16:17

  • Sobrecargar el concepto de nulo con un significado que no sea “el universo no sabe” es más débil que usar una enumeración de 3 (o más) valores. También hace que la lectura del código que pasa los parámetros al método sea más explícita.

    – vector azul

    26 de junio de 2012 a las 19:08

  • O #4: Boolean isSchrodinger‎CatAlive = null; (lo siento, no pude resistirme ;)).

    – Matthieu

    13 de diciembre de 2013 a las 23:02

avatar de usuario
Tomasz Nurkiewicz

casi nunca uso Boolean porque su semántica es vaga y oscura. Básicamente tienes una lógica de 3 estados: verdadero, falso o desconocido. A veces es útil usarlo cuando, por ejemplo, le dio al usuario una opción entre dos valores y el usuario no respondió en absoluto y realmente desea conocer esa información (piense: columna de base de datos anulable).

No veo ninguna razón para convertir de boolean a Boolean ya que introduce sobrecarga de memoria adicional, posibilidad de NPE y menos tipeo. Típicamente uso incómodo BooleanUtils.isTrue() para hacer mi vida un poco más fácil con Boolean.

La única razón de la existencia de Boolean es la capacidad de tener colecciones de Boolean tipo (los genéricos no permiten booleanasí como todas las demás primitivas).

  • Sin embargo, es una biblioteca externa (Apache commons).

    – nhahtdh

    25 de junio de 2012 a las 7:59


  • Para la lógica multivaluada, es preferible usar enumeraciones. Por lo tanto, Boolean debe dejarse para las variables de (auto) boxeo para su uso en estructuras de datos.

    – jpe

    25 de junio de 2012 a las 8:03

  • Cuando se usa Boolean, una prueba conveniente para evitar excepciones de puntero nulo es Boolean.TRUE.equals(myBooleanObject) o Boolean.FALSE.equals(myBooleanObject).

    – Christopher Peisert

    25 de junio de 2012 a las 8:20


  • Un objeto booleano tiene solo dos estados: true y false. null es no un estado del objeto, sino un estado de la referencia del objeto.

    – Lame caliente

    25 de junio de 2012 a las 20:04

  • Deje que apache commons sea como “Alguien podría equivocarse al evaluar los valores booleanos… hagamos una isTrue() método…” que suena como la cosa más tonta en la historia de las funciones de utilidad. Y, sin embargo, de alguna manera, es útil… ese es el mayor wtf aquí.

    – CorsiKa

    6 de julio de 2012 a las 16:49

avatar de usuario
usuario606723

Vaya, ¿qué diablos? ¿Soy solo yo o todas estas respuestas son incorrectas o al menos engañosas?

La clase Boolean es un contenedor alrededor del tipo primitivo booleano. El uso de este contenedor es poder pasar un booleano en un método que acepta un objeto o genérico. es decir, vectorial.

Un objeto booleano NUNCA puede tener un valor nulo. Si tu referencia a un booleano es nulo, simplemente significa que su booleano nunca se creó.

Usted puede encontrar esto útil: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

Una referencia booleana nula solo debe usarse para desencadenar una lógica similar a la que tenga cualquier otra referencia nula. Usarlo para la lógica de tres estados es torpe.

EDITAR: aviso, que Boolean a = true; es una declaración engañosa. Esto realmente equivale a algo más cercano a Boolean a = new Boolean(true);
Por favor vea autoboxing aquí: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

Quizás de ahí viene gran parte de la confusión.

EDIT2: Lea los comentarios a continuación. Si alguien tiene una idea de cómo reestructurar mi respuesta para incorporar esto, hágalo.

  • No entiendo su declaración “Un valor booleano NUNCA puede tener un valor nulo”. Puedo crear un booleano (Boolean a = true;) y luego establezca a en nulo (a = null;). Puede que no sea elegante o sabio, pero es posible.

    – peter.murray.rust

    25 de junio de 2012 a las 14:51

  • Cuando tu lo hagas Boolean a; a es un puntero a un objeto booleano. Si usted a = null; No ha establecido su booleano en nulo, ha establecido su referencia en nulo. Hacer Boolean a = null; a.booleanValue(); En este caso, usted ni siquiera creado un objeto booleano y, por lo tanto, arrojará una excepción de puntero nulo. Avísame si necesitas más instrucciones.

    – usuario606723

    25 de junio de 2012 a las 14:59

  • Además, cuando haces Boolean a = true;Hace algún tipo de magia que en realidad se interpreta como Boolean a = new Boolean(true); Probablemente eso no sea completamente correcto por razones de rendimiento, pero debe darse cuenta de que el booleano sigue siendo un objeto.

    – usuario606723

    25 de junio de 2012 a las 15:04

  • @missingno, todo el código que trata con cualquier objeto tiene que lidiar con esto. Una referencia de objeto puede ser nula o no. Este no es un caso especial y no requiere una consideración especial.

    – usuario606723

    25 de junio de 2012 a las 16:54

  • Te estás perdiendo mi punto @missingno. Estoy de acuerdo en que debemos considerar valores de referencia nulos. Nunca estuve argumentando en contra de eso. Pero tenemos que hacer esto para CUALQUIER OBJETO DE REFERENCIA. Una referencia booleana nula no es un caso especial. Y, por lo tanto, los valores de referencia booleanos nulos no requieren una consideración especial.

    – usuario606723

    25 de junio de 2012 a las 20:34

Hay tres razones rápidas:

  • para representar los valores booleanos de la base de datos, que pueden ser true, false o null
  • para representar esquemas XML xsd:boolean valores declarados con xsd:nillable="true"
  • para poder utilizar tipos genéricos: List<Boolean> – no puedes usar List<boolean>

avatar de usuario
peter.murray.rust

RESPUESTA A LA PROPIA PREGUNTA: Pensé que sería útil responder a mi propia pregunta, ya que he aprendido mucho de las respuestas. Esta respuesta está destinada a ayudar a aquellos, como yo, que no tienen una comprensión completa de los problemas. Si uso un lenguaje incorrecto por favor corrígeme.

  • El “valor” nulo no es un valor y es fundamentalmente diferente de true y false. Es la ausencia de un puntero a los objetos. Por lo tanto, pensar que Boolean tiene 3 valores es fundamentalmente incorrecto
  • La sintaxis de Boolean está abreviada y oculta el hecho de que la referencia apunta a Objetos:

    Boolean a = true;

oculta el hecho de que true es un objeto Otras asignaciones equivalentes podrían ser:

Boolean a = Boolean.TRUE;

o

Boolean a = new Boolean(true);
  • La sintaxis abreviada

    if (a) ...

es diferente de la mayoría de las otras asignaciones y oculta el hecho de que a podría ser una referencia de objeto o una primitiva. Si un objeto es necesario probar para null para evitar la NPE. Para mí es psicológicamente más fácil recordar esto si hay una prueba de igualdad:

if (a == true) ...

donde se nos podría solicitar que realicemos una prueba de nulo. Entonces, la forma abreviada solo es segura cuando a es un primitivo.

Para mí ahora tengo las recomendaciones:

  • Nunca use nulo para una lógica de 3 valores. Solo usa verdadero y falso.
  • Nunca volver Boolean de un método como podría ser null. solo regreso boolean.
  • Uso único Boolean para envolver elementos en contenedores, o argumentos para métodos donde se requieren objetos

  • No use “nuevo booleano (lo que sea)”. Eso creará una instancia de un nuevo booleano en el montón. Sin embargo, Boolean es inmutable. Use “Boolean.valueOf(whatever)” que creará una referencia que apunta a Boolean.TRUE o Boolean.False dependiendo de lo que sea.

    – simbo1905

    1 de julio de 2012 a las 21:43

  • Uno de los muchos problemas con Java (en mi humilde opinión después de 12 años) es la inconsistencia del enfoque de los valores nulos que también tienen los lenguajes antiguos. Echando un vistazo a Scala, tiene el concepto de una Opción escrita que puede ser nula o puede tener un valor (subclases Ninguno o Algunos). Luego puede llamar a myOption.getOrElse(defaultValue). Ver scala-lang.org/api/current/scala/Option.html no hay nada complejo acerca de esta función. Sin embargo, como está integrado en el nuevo lenguaje JVM, muchas bibliotecas lo utilizan. Eso hace que la escala “arregle” algunos de los problemas de Java del “siglo pasado”, pero aún se compila en archivos de clase que se ejecutan en el JRE.

    – simbo1905

    1 de julio de 2012 a las 21:49


Las clases contenedoras para primitivas se pueden usar donde se requieren objetos, las colecciones son un buen ejemplo.

Imagina que necesitas por alguna razón almacenar una secuencia de boolean en un ArrayListesto se puede hacer boxeando boolean en Boolean.

Hay algunas palabras sobre esto. aquí

De la documentación:

Como sabe cualquier programador de Java, no puede poner un int (u otro valor primitivo) en una colección. Las colecciones solo pueden contener referencias a objetos, por lo que debe encuadrar los valores primitivos en la clase contenedora adecuada (que es Integer en el caso de int). Cuando saca el objeto de la colección, obtiene el número entero que puso; si necesita un int, debe desempaquetar el Integer usando el método intValue. Todo este empaquetado y desempaquetado es una molestia y desordena su código. La función de autoboxing y unboxing automatiza el proceso, eliminando el dolor y el desorden.

http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

  • No use “nuevo booleano (lo que sea)”. Eso creará una instancia de un nuevo booleano en el montón. Sin embargo, Boolean es inmutable. Use “Boolean.valueOf(whatever)” que creará una referencia que apunta a Boolean.TRUE o Boolean.False dependiendo de lo que sea.

    – simbo1905

    1 de julio de 2012 a las 21:43

  • Uno de los muchos problemas con Java (en mi humilde opinión después de 12 años) es la inconsistencia del enfoque de los valores nulos que también tienen los lenguajes antiguos. Echando un vistazo a Scala, tiene el concepto de una Opción escrita que puede ser nula o puede tener un valor (subclases Ninguno o Algunos). Luego puede llamar a myOption.getOrElse(defaultValue). Ver scala-lang.org/api/current/scala/Option.html no hay nada complejo acerca de esta función. Sin embargo, como está integrado en el nuevo lenguaje JVM, muchas bibliotecas lo utilizan. Eso hace que la escala “arregle” algunos de los problemas de Java del “siglo pasado”, pero aún se compila en archivos de clase que se ejecutan en el JRE.

    – simbo1905

    1 de julio de 2012 a las 21:49


Boolean wrapper es útil cuando desea saber si se asignó un valor o no, aparte de true y false. Tiene los siguientes tres estados:

  • Verdadero
  • Falso
  • No definido cual es null

Mientras boolean tiene solo dos estados:

  • Verdadero
  • Falso

La diferencia anterior lo hará útil en Listas de Boolean valores que pueden tener True, False o Null.

  • No, no tiene un estado nulo, esa es la referencia.

    – Matsemann

    25 de junio de 2012 a las 21:07

  • Lo que quise decir es que Bolean se puede usar para True/False y Not Defined definidos.

    – Ramesh PVK

    26 de junio de 2012 a las 4:36

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad