Respuestas:
Estos son los operadores AND bit a bit y OR bit a bit.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Gracias a Carlos por señalar la sección correspondiente en las especificaciones del lenguaje Java ( 15.22.1 , 15.22.2 ) con respecto a los diferentes comportamientos del operador en función de sus entradas.
De hecho, cuando ambas entradas son booleanas, los operadores se consideran Operadores lógicos booleanos y se comportan de manera similar a Condicional-Y (&&
) y Condicional-O ( ||
) excepto por el hecho de que no hacen cortocircuito, por lo que mientras lo siguiente es seguro :
if((a != null) && (a.something == 3)){
}
Esto no es:
if((a != null) & (a.something == 3)){
}
"Cortocircuito" significa que el operador no necesariamente examina todas las condiciones. En los ejemplos anteriores, &&
examinará la segunda condición solo cuandoa
no lo sea null
(de lo contrario, la declaración completa devolverá falso, y sería discutible examinar las siguientes condiciones de todos modos), por lo que la declaración de a.something
no generará una excepción o se considerará "segura . "
El &
operador siempre examina cada condición en la cláusula, por lo que en los ejemplos anteriores, a.something
se puede evaluar cuando a
de hecho es un null
valor, lo que genera una excepción.
Creo que estás hablando del significado lógico de ambos operadores, aquí tienes un resumen de tabla:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
La evaluación de cortocircuito , la evaluación mínima o la evaluación de McCarthy (después de John McCarthy) es la semántica de algunos operadores booleanos en algunos lenguajes de programación en los que el segundo argumento se ejecuta o evalúa solo si el primer argumento no es suficiente para determinar el valor del expresión: cuando el primer argumento de la función AND se evalúa como falso, el valor general debe ser falso; y cuando el primer argumento de la función OR se evalúa como verdadero, el valor general debe ser verdadero.
No seguro significa que el operador siempre examina todas las condiciones de la cláusula, por lo que en los ejemplos anteriores, 1 / x puede evaluarse cuando la x es, de hecho, un valor 0, lo que genera una excepción.
Sé que hay muchas respuestas aquí, pero todas parecen un poco confusas. Entonces, después de investigar un poco de la guía de estudio del oráculo de Java, se me ocurrieron tres escenarios diferentes de cuándo usar && o &. Los tres escenarios son AND lógico , AND bit a bit y AND booleano .
Y lógico: Y
lógico (también conocido como Y condicional) utiliza el operador && . Es el significado de cortocircuito: si el operando izquierdo es falso, entonces el operando derecho no será evaluado.
Ejemplo:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
En el ejemplo anterior, el valor impreso en la consola de x será 0, porque el primer operando en la instrucción if es falso, por lo que java no tiene necesidad de calcular (1 == ++ x) por lo tanto, x no se calculará.
AND bit a bit: AND bit a bit utiliza el operador & . Se utiliza para realizar una operación bit a bit sobre el valor. Es mucho más fácil ver lo que está sucediendo al observar la operación en números binarios, por ejemplo:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Como puede ver en el ejemplo, cuando las representaciones binarias de los números 5 y 12 están alineadas, entonces un Y preformado bit a bit solo producirá un número binario donde el mismo dígito en ambos números tiene un 1. Por lo tanto, 0101 y 1100 == 0100. Que en decimal es 5 y 12 == 4.
AND booleano: ahora el operador AND booleano se comporta de manera similar y diferente tanto al AND bit a bit como al AND lógico. Me gusta pensar en ello como una preforma de bit a bit AND entre dos valores booleanos (o bits), por lo tanto, usa & operador . Los valores booleanos también pueden ser el resultado de una expresión lógica.
Devuelve un valor verdadero o falso, muy parecido al Y lógico, pero a diferencia del Y lógico, no está cortocircuitado. La razón es que, para realizar ese AND bit a bit, debe conocer el valor de los operandos izquierdo y derecho. Aquí hay un ex:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Ahora, cuando se ejecute la instrucción if, se ejecutará la expresión (1 == ++ x), aunque el operando izquierdo sea falso. Por lo tanto, el valor impreso para x será 1 porque se incrementó.
Esto también se aplica a OR lógico (||), OR bit a bit (|) y OR booleano (|) Espero que esto aclare algo de confusión.
to preform that bitwise AND, it must know the value of both left and right operands
Esto no me suena bien. Para realizar una BITWISE AND
no es necesario conocer el operando derecho para poder averiguar el resultado si el operando izquierdo es FALSE
. Lo que explicas es correcto, pero el razonamiento que dices no me lo parece, al menos a mí ..
Los operadores && y || están en cortocircuito, lo que significa que no evaluarán su expresión de la derecha si el valor de la expresión de la izquierda es suficiente para determinar el resultado.
& y | proporcionan el mismo resultado que && y || operadores. La diferencia es que siempre evalúan ambos lados de la expresión donde as && y || deje de evaluar si la primera condición es suficiente para determinar el resultado.
&&
evalúa ambos resultados mientras que ||
devuelve solo si la primera condición es verdadera.
( 2 & 4 )
evalúa a false
, mientras que ( 2 && 4 )
evalúa a true
. ¿Cómo es exactamente el mismo resultado?
2 & 4
da como resultado un número entero, no un booleano (cero en este caso). 2 && 4
no compilará, && solo aceptará booleanos. Java no permite mezclar booleanos e ints: cero no es false
, false
no es cero ...
&&
solo evalúa el segundo operando si el primer operando es true
.
En Java, los operadores únicos &, |, ^,! dependen de los operandos. Si ambos operandos son enteros, se realiza una operación bit a bit. Si ambos son booleanos, se realiza una operación "lógica".
Si ambos operandos no coinciden, se genera un error de tiempo de compilación.
Los operadores dobles &&, || se comportan de manera similar a sus contrapartes individuales, pero ambos operandos deben ser expresiones condicionales, por ejemplo:
if ((a <0) && (b <0)) {...} o de manera similar, if ((a <0) || (b <0)) {...}
fuente: programación java lang 4th ed
&
y |
son operadores bit a bit en tipos integrales (por ejemplo int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
y ||
operar solo con valores booleanos (y cortocircuito, como ya han dicho otras respuestas).
&
y |
también son operadores booleanos en tipos booleanos.
Tal vez sea útil saber que los operadores AND bit a bit y OR bit a bit siempre se evalúan antes que el AND condicional y el OR condicional usados en la misma expresión.
if ( (1>2) && (2>1) | true) // false!
&&; || son operadores lógicos .... cortocircuito
&; | son operadores lógicos booleanos .... Sin cortocircuito
Pasando a las diferencias en la ejecución de expresiones. Los operadores bit a bit evalúan ambos lados independientemente del resultado del lado izquierdo. Pero en el caso de evaluar expresiones con operadores lógicos, la evaluación de la expresión de la mano derecha depende de la condición de la mano izquierda.
Por ejemplo:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Esto imprimirá i = 26; j = 25, como la primera condición es falsa, la condición de la mano derecha se omite ya que el resultado es falso de todos modos, independientemente de la condición del lado derecho (cortocircuito)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Pero, esto imprimirá i = 26; j = 26,
Si una expresión que involucra el booleano & se evalúa operador , se evalúan ambos operandos. Luego, el operador & se aplica al operando.
Cuando una expresión que incluye && se evalúa operador , se evalúa el primer operando. Si el primer operando se evalúa como falso, se omite la evaluación del segundo operando.
Si el primer operando devuelve un valor verdadero, se evalúa el segundo operando. Si el segundo operando devuelve un valor verdadero, entonces el operador && se aplica al primer y segundo operandos.
Similar para | y ||.
Si bien la diferencia básica es que &
se usa principalmente para operaciones bit a bit long
, int
o byte
donde se puede usar para una especie de máscara, los resultados pueden diferir incluso si lo usa en lugar de lógico &&
.
La diferencia es más notable en algunos escenarios:
El primer punto es bastante sencillo, no causa errores, pero lleva más tiempo. Si tiene varias comprobaciones diferentes en una declaración condicional, coloque las que sean más baratas o con más probabilidades de fallar a la izquierda.
Para el segundo punto, vea este ejemplo:
if ((a != null) & (a.isEmpty()))
Esto falla null
, ya que la evaluación de la segunda expresión produce un NullPointerException
. Operador lógico&&
es perezoso, si el operando izquierdo es falso, el resultado es falso sin importar cuál sea el operando derecho.
Ejemplo para el tercer punto: digamos que tenemos una aplicación que usa DB sin activadores ni cascadas. Antes de eliminar un objeto Edificio, debemos cambiar el edificio de un objeto Departamento a otro. Digamos también que el estado de la operación se devuelve como booleano (verdadero = éxito). Luego:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Esto evalúa ambas expresiones y, por lo tanto, realiza la eliminación del edificio incluso si la actualización del departamento falló por algún motivo. Con&&
, funciona según lo previsto y se detiene después del primer fallo.
En cuanto a a || b
, es equivalente a !(!a && !b)
, se detiene si a
es cierto, no se necesita más explicación.