Booleano vs booleano en Java

195

Hay discusiones sobre Integervs inten Java. El valor predeterminado del primero es nullmientras que en el segundo es 0. ¿Qué tal Booleanvs boolean?

Una variable en mi aplicación puede tener 0/ 1valores. Me gustaría usar boolean/ Booleany prefiero no usar int. ¿Puedo usar Boolean/ en su booleanlugar?

Neel
fuente
2
Por razones de diseño del sistema, elegiría Boolean ya que tiene la opción "El usuario aún no ha decidido", que no es igual a "verdadero" ni a "falso". Usaría primitivo booleano solo en casos si estoy 100% seguro de que las opciones verdadero / falso son suficientes. La opción NULL en la base de datos generalmente está disponible sin problemas (o simplemente eliminando las restricciones NOT NULL en una demanda posterior)
CsBalazsHungary
2
Duplicado exacto de ¿Cuál es la diferencia entre booleano y booleano en Java? (porque GWT no hace la diferencia).
Dan Dascalescu

Respuestas:

270

, puedes usar Boolean/ en su booleanlugar.

El primero es Object y el segundo es de tipo primitivo.

  • En el primero, obtendrá más métodos que serán útiles.

  • El segundo es barato teniendo en cuenta el gasto de memoria. El segundo le ahorrará mucha más memoria, así que hágalo.

Ahora elige tu camino.

Jigar Joshi
fuente
70
Podría haber dicho esto como "el segundo le ahorrará mucha más memoria, así que hágalo". Los métodos útiles en Boolean se pueden invocar principalmente sin tener una instancia de ello.
DJClayworth
3
Siempre que use en su lugar Boolean.valueOf (valor) del nuevo Boolean (valor), la memoria no debería ser una preocupación.
Greg Case
2
para AsyncTask, solo puede usar en Booleanlugar de boolean.
Raptor
98
Cabe señalar que un booleano en realidad tiene 3 estados ... true, falsey nulldonde un booleano tiene los 2 estados lógicos ( truey false)
respectTheCode
14
Boolean is trillean :)
Topera
50

Boolean envuelve el tipo primitivo booleano. En JDK 5 y versiones posteriores , Oracle (o Sun antes de que Oracle los comprara) introdujo el autoboxing / unboxing , que esencialmente le permite hacer esto

boolean result = Boolean.TRUE;

o

Boolean result = true; 

Lo que esencialmente hace el compilador,

Boolean result = Boolean.valueOf(true);

Entonces, para su respuesta, es SÍ.

Buhake Sindi
fuente
44
Nota: No siempre se puede asignar de forma segura Booleana a boolean. Si Booleanes nulle intenta asignarlo a a boolean, arrojará un NullPointerExceptionen tiempo de ejecución.
Duncan Luk
si es Booleanuna clase, ¿por qué el valor siempre es falso incluso si cambié el valor de otra clase que hace referencia a la misma variable booleana? ¿Cuál es el punto de esto Booleansi no podemos hacer referencia a diferentes clases de instancia / pasar como argumento?
usuario924
encontró una respuesta, podemos utilizar AtomicBooleany hacer referencia a ella desde las clases de diferencia
user924
35

Estoy extendiendo un poco las respuestas proporcionadas (ya que hasta ahora se concentran en su terminología "propia" / artificial centrándose en la programación de un lenguaje en particular en lugar de ocuparse de la imagen más amplia detrás de la escena de la creación de los lenguajes de programación , en general, es decir, cuando las cosas como las consideraciones de seguridad de tipo versus memoria hacen la diferencia):

int no es booleano

Considerar

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

con salida

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

El código Java en la tercera línea (bar)?1:0ilustra que la barra ( booleana ) no se puede convertir (convertir) implícitamente en un int . Menciono esto no para ilustrar los detalles de la implementación detrás de JVM, sino para señalar que, en términos de consideraciones de bajo nivel (como el tamaño de la memoria), uno tiene que preferir los valores sobre la seguridad de tipo. Especialmente si ese tipo de seguridad no se usa verdadera / totalmente como en los tipos booleanos donde los controles se realizan en forma de

si el valor \ en {0,1} se convierte al tipo booleano, de lo contrario arroje una excepción.

Todo para indicar que {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Parece una exageración, ¿verdad? La seguridad de tipo es realmente importante en los tipos definidos por el usuario, no en la conversión implícita de primitivas (aunque las últimas se incluyen en la primera).

Los bytes no son tipos o bits

Tenga en cuenta que en la memoria su variable del rango de {0,1} seguirá ocupando al menos un byte o una palabra (xbits dependiendo del tamaño del registro) a menos que esté especialmente cuidado (por ejemplo, bien guardado en la memoria - 8 "booleano" bits en 1 byte - adelante y atrás).

Al preferir la seguridad de tipo (como poner / envolver el valor en una caja de un tipo particular) sobre el empaquetado de valor adicional (por ejemplo, usar cambios de bits o aritmética), se elige escribir menos código en lugar de ganar más memoria. (Por otro lado, siempre se puede definir un tipo de usuario personalizado que facilitará toda la conversión que no valga más que booleana).

palabra clave versus tipo

Finalmente, su pregunta es sobre la comparación de palabras clave versus tipo . Creo que es importante explicar por qué o cómo exactamente obtendrá rendimiento al usar / preferir palabras clave ("marcadas" como primitivas ) sobre los tipos (clases compuestas definibles por el usuario normales que usan otra clase de palabras clave ) o en otras palabras

boolean foo = true;

vs.

Boolean foo = true;

La primera "cosa" (tipo) no se puede extender (subclasificar) y no sin una razón. Efectivamente, la terminología de Java de las clases primitivas y envolventes se puede traducir simplemente en un valor en línea (un LITERAL o una constante que se sustituye directamente por el compilador cada vez que es posible inferir la sustitución o, de lo contrario, recurrir al ajuste del valor).

La optimización se logra debido a trivial:

"Menos operaciones de lanzamiento de tiempo de ejecución => más velocidad".

Es por eso que cuando se realiza la inferencia de tipo real, puede (todavía) terminar instanciando la clase de ajuste con toda la información de tipo si es necesario (o convertir / convertir en tal).

Entonces, la diferencia entre boolean y Boolean está exactamente en Compilation y Runtime (un poco lejos pero casi como una instancia de vs. getClass () ).

Finalmente, el autoboxing es más lento que los primitivos.

Tenga en cuenta que Java puede hacer autoboxing es solo un "azúcar sintáctico". No acelera nada, solo le permite escribir menos código. Eso es. Aún se realiza la conversión y el ajuste en el contenedor de información de tipo. Por razones de rendimiento, elija la aritmética, que siempre omitirá la limpieza adicional al crear instancias de clase con información de tipo para implementar la seguridad de tipo. La falta de seguridad de tipo es el precio que paga para obtener rendimiento. Para el código con expresiones de valor booleano, la seguridad de tipo (cuando escribe menos y, por lo tanto, código implícito ) sería crítica, por ejemplo, para los controles de flujo if-then-else.

Yauhen Yakimovich
fuente
16

Puede usar las constantes booleanas , Boolean.TRUEy en Boolean.FALSElugar de 0y 1. Puede crear su variable a partir de tipo booleansi primitivo es lo que busca. De esta manera no tendrás que crear nuevos Booleanobjetos.

Frijoles
fuente
3

Básicamente, los booleanos representan un tipo de datos primitivo donde los booleanos representan un tipo de datos de referencia. Esta historia se inicia cuando Java quiere orientarse exclusivamente a los objetos. Se proporciona un concepto de clase envolvente para utilizar el tipo de datos primitivos.

boolean b1;
Boolean b2;

b1Y b2no son lo mismo.

Sachin Jadhav
fuente
3

Una observación: (aunque esto puede pensarse en el efecto secundario)

ser un booleano primitivo puede decir sí o no.

Boolean es un objeto (puede referirse a sí o no o 'no sabe', es decir, nulo)

Sudip Bhandari
fuente
1

Puede usar booleano / booleano. La simplicidad es el camino a seguir. Si no necesita una API específica (Colecciones, Streams, etc.) y no prevé que las necesitará, use una versión primitiva (booleana).

  1. Con primitivas, garantiza que no pasará valores nulos.
    No caerás en trampas como esta. El siguiente código arroja NullPointerException (de: booleanos, operadores condicionales y autoboxing ):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. Use booleano cuando necesite un objeto, por ejemplo:

    • Corriente de booleanos,
    • Opcional
    • Colecciones de booleanos
Witold Kaczurba
fuente