Efecto de un operador bit a bit en un booleano en Java

Se supone que los operadores bit a bit viajan variables y operan en ellas poco a poco. En el caso de enteros, largos, caracteres, esto tiene sentido. Estas variables pueden contener la gama completa de valores impuestos por su tamaño.

En el caso de los booleanos, sin embargo, un booleano puede contener solo dos valores. 1 = verdadero o 0 = falso Pero el tamaño del booleano no está definido. Puede ser tan grande como un byte o tan pequeño.

Entonces, ¿cuál es el efecto de usar un operador bit a bit en un booleano? ¿La JVM esencialmente lo traduce a un operador lógico normal y continúa? ¿Trata el booleano como una entidad de bit único para el propósito de la operación? ¿O el resultado no está definido junto con el tamaño de un booleano?

Los operadores &, ^, y | son operadores bit a bit cuando los operandos son tipos integrales primitivos. Son operadores lógicos cuando los operandos son booleanos y se especifica su comportamiento en este último caso. Consulte la sección 15.22.2 de la Especificación del lenguaje Java para más detalles.

El uso del operador bit a bit puede eludir el comportamiento de cortocircuito:

 boolean b = booleanExpression1() && booleanExpression2(); boolean b = booleanExpression1() & booleanExpression2(); 

Si booleanExpression1() evalúa como false , entonces
booleanExpression2() no se evalúa en el primer caso, y
booleanExpression2() (y los efectos secundarios que pueda tener) se evalúa en el segundo caso,

Más allá de lo que está cubierto en las otras respuestas, vale la pena señalar que && y || tienen precedencia diferente de & y | .

Extracto de la tabla de precedencia (con la precedencia más alta en la parte superior).

 bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | logical AND && logical OR || 

¿Qué significa esto para ti?

Absolutamente nada, siempre y cuando te apegues a solo & y | o solo && y || .

Pero, desde | tiene una precendencia mayor que && (a diferencia de || , que tiene una precedencia más baja), mezclarlas libremente podría conducir a un comportamiento inesperado.

Entonces a && b | c && d a && b | c && d es lo mismo que a && (b | c) && d ,
a diferencia de a a && b || c && d a && b || c && d que sería (a && b) || (c && d) (a && b) || (c && d) .

Para demostrar que no son lo mismo, considera un extracto de la tabla de verdad:

 a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d) F | T | T | T | T | F | T | F | T ^ ^ |- not the same -| 

Si desea O tiene una precedencia mayor que AND, puede usar | y && juntos, pero esto no es recomendable.

Pero deberías ponerlos entre paréntesis para aclarar la precedencia siempre que uses diferentes símbolos, es decir (a && b) || c (a && b) || c (corchetes para aclarar la precedencia), a && b && c (no se necesitan corchetes).

Incluso si funciona, no deberías hacerlo. Las especificaciones de idioma definen operadores bit a bit solo cuando ambos operandos son de tipos enteros primitivos o ambos son de tipo booleano. Yo diría que en cualquier otro caso los resultados no están definidos:

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228