¿Cuál es la diferencia entre & y && en Java?

168

Siempre pensé que el &&operador en Java se usa para verificar si sus operandos booleanos lo son true, y el &operador se usa para realizar operaciones en dos tipos enteros.

Recientemente supe que el &operador también se puede usar para verificar si sus operandos booleanos son true, la única diferencia es que verifica el operando RHS incluso si el operando LHS es falso.

¿El &operador en Java está sobrecargado internamente? ¿O hay algún otro concepto detrás de esto?

Comunidad
fuente
Doble realiza acceso directo si es posible.
Nicholas Hamilton

Respuestas:

278

& <- verifica ambos operandos
&& <- deja de evaluar si el primer operando se evalúa como falso ya que el resultado será falso

(x != 0) & (1/x > 1)<- esto significa evaluar y (x != 0)luego evaluar y (1/x > 1)luego hacer el &. El problema es que para x = 0 esto arrojará una excepción.

(x != 0) && (1/x > 1)<- esto significa evaluar (x != 0)y solo si esto es cierto, entonces evaluar (1/x > 1)si tiene x = 0, entonces esto es perfectamente seguro y no arrojará ninguna excepción si (x! = 0) se evalúa como falso, todo se evalúa directamente como falso sin evaluar el (1/x > 1).

EDITAR:

exprA | exprB<- esto significa evaluar, exprAluego evaluar y exprBluego hacer el |.

exprA || exprB<- esto significa evaluar exprAy solo si esto es falseevaluar exprBy hacer el ||.

ITroubs
fuente
77
¿Cuál es la razón para escribir uno y / o | en la declaración if? Nunca será más rápido que && y ||. ¿Por qué queremos verificar la segunda condición si ya podemos tener una respuesta? ¿Puede proporcionar un ejemplo realista, por favor?
Michu93
14
@ Michu93: Un ejemplo sería si la segunda condición es una llamada de función que tiene un efecto secundario que siempre necesita. Como los efectos secundarios generalmente deben evitarse, solo habrá casos raros en los que lo necesite, y no puedo pensar en un ejemplo realista en este momento.
Heinzi
54

Además de no ser un evaluador perezoso al evaluar ambos operandos, creo que las características principales de los operadores bit a bit comparan cada byte de operandos como en el siguiente ejemplo:

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100
suat
fuente
2
La pregunta es sobre operaciones lógicas booleanas, no operaciones bit a bit.
Marqués de Lorne
21
@EJP Todavía ayuda a los googlers como yo, que solo leen el título.
Ad Infinitum
29
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
Torres
fuente
Gracias Andreas por la edición, tal vez esta otra pregunta también ayude: stackoverflow.com/questions/4014535/vs-and-vs
Torres
11

Depende del tipo de argumentos ...

Para argumentos enteros, el ampersand único ("&") es el operador "bit-wise AND". El doble ampersand ("&&") no está definido para nada más que dos argumentos booleanos.

Para argumentos booleanos, el ampersand simple constituye el operador "incondicional" AND lógico, mientras que el ampersand doble ("&&") es el operador "AND lógico condicional". Es decir que el ampersand único siempre evalúa ambos argumentos, mientras que el ampersand doble solo evaluará el segundo argumento si el primer argumento es verdadero.

Para todos los demás tipos de argumentos y combinaciones, debe producirse un error en tiempo de compilación.

desarrollador
fuente
9

&& es un operador de cortocircuito mientras que & es un operador AND.

Prueba esto.

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false
Príncipe John Wesley
fuente
7

es como se especifica en el JLS (15.22.2) :

Cuando ambos operandos de a &, ^ o | operador son de tipo booleano o booleano, entonces el tipo de la expresión de operador bit a bit es booleano. En todos los casos, los operandos están sujetos a la conversión de unboxing (§5.1.8) según sea necesario.

Para &, el valor del resultado es verdadero si ambos valores de operando son verdaderos; de lo contrario, el resultado es falso.

Para ^, el valor del resultado es verdadero si los valores del operando son diferentes; de lo contrario, el resultado es falso.

Para |, el valor del resultado es falso si ambos valores de operando son falsos; de lo contrario, el resultado es verdadero.

El "truco" es que &es un operador bit a bit entero , así como un operador lógico booleano . Entonces, ¿por qué no? Ver esto como un ejemplo de sobrecarga del operador es razonable.

Andreas Dolk
fuente
7

Creo que mi respuesta puede ser más comprensible:

Hay dos diferencias entre &y &&.

Si usan como lógico Y

&y &&puede ser lógico AND, cuando el resultado de la expresión izquierda &o &&derecha es verdadero, todo el resultado de la operación puede ser verdadero.

cuando &y &&como es lógico AND, hay una diferencia:

cuando se usa &&como lógico AND, si el resultado de la expresión izquierda es falso, la expresión derecha no se ejecutará.

Toma el ejemplo:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

Si usa &:

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

Otro ejemplo más:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}

int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

& se puede utilizar como operador de bits

&se puede usar como ANDoperador Bitwise , &&no se puede.

El operador AND "&" bit a bit produce 1 si y solo si ambos bits en sus operandos son 1. Sin embargo, si ambos bits son 0 o ambos bits son diferentes, entonces este operador produce 0. Para ser más preciso a nivel bit Y el operador "&" devuelve 1 si alguno de los dos bits es 1 y devuelve 0 si alguno de los bits es 0. 

Desde la página wiki:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

aeronave
fuente
4

'&&': es un operador lógico AND que produce un valor booleano de verdadero o falso basado en la relación lógica de sus argumentos.

Por ejemplo: - Condición1 && Condición2

Si la Condición1 es falsa, entonces (Condición1 && Condición2) siempre será falsa, esa es la razón por la cual este operador lógico también se conoce como Operador de Cortocircuito porque no evalúa otra condición. Si la Condición1 es falsa, no hay necesidad de evaluar Condtiton2.

Si la Condición1 es verdadera, entonces se evalúa la Condición2, si es verdadera, el resultado general será verdadero; de lo contrario, será falso.

'&': - es un operador AND a nivel de bits. Produce un uno (1) en la salida si ambos bits de entrada son uno. De lo contrario, produce cero (0).

Por ejemplo:-

int a = 12; // la representación binaria de 12 es 1100

int b = 6; // la representación binaria de 6 es 0110

int c = (a & b); // la representación binaria de (12 y 6) es 0100

El valor de c es 4.

para referencia, consulte este http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html

satish
fuente
3

&&y ||se llaman operadores de cortocircuito. Cuando se usan, for ||- si el primer operando se evalúa como true, entonces el resto de los operandos no se evalúan. Para &&: si el primer operando se evalúa como false, el resto de ellos no se evalúa en absoluto.

entonces, if (a || (++x > 0))en este ejemplo, la variable x no se incrementará si a true.

ACV
fuente
3

Con booleanos, no hay diferencia de salida entre los dos. Puede intercambiar && y & or || y | y nunca cambiará el resultado de tu expresión.

La diferencia se encuentra detrás de la escena donde se procesa la información. Cuando endereza una expresión "(a! = 0) & (b! = 0)" para a = 0 y b = 1, sucede lo siguiente:

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

Cuando escribe una expresión (a != 0) && ( b != 0)cuando a = 0 y b = 1, sucede lo siguiente:

a != 0 -->false
expression returns false

Menos pasos, menos procesamiento, mejor codificación, especialmente cuando se hacen muchas expresiones booleanas o argumentos complicados.

Ryan
fuente
2
Cambiará el resultado general de la expresión si los operandos tienen efectos secundarios.
Marqués de Lorne
3

Además de && y || siendo cortocircuito, también considere la precedencia del operador al mezclar las dos formas. Creo que no será inmediatamente evidente para todos que resultado1 y resultado2 contienen valores diferentes.

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c
mgr326639
fuente
0

& es un operador bit a bit más utilizado para verificar ambas condiciones porque a veces necesitamos evaluar ambas condiciones. Pero el operador lógico && pasa a la segunda condición cuando la primera condición da verdadero.

Yasir Shabbir Choudhary
fuente
0

todas las respuestas son great, y parece que hay nomás respuestas, is needed pero simplemente me pregunté algo sobre el &&operador llamadodependent condition

En las expresiones que usan el operador &&, una condición, a la que llamaremos esto, dependent conditionpuede requerir que otra condición sea verdadera para que la evaluación de la condición dependiente sea significativa.

En este caso, la condición dependiente debe colocarse después del operador && para evitar errores.

Considera la expresión (i != 0) && (10 / i == 2). La condición dependiente (10 / i == 2)debe ser appear afterel &&operador para evitar la posibilidad de división por cero.

otro ejemplo (myObject != null) && (myObject.getValue() == somevaluse)

y otra cosa: &&y ||se llama Evaluación de cortocircuito debido a que el segundo argumento se ejecuta o evalúa only ifel firstargumento no not sufficea determinela valuede laexpression

Referencias: Java ™ How To Program (Early Objects), Décima edición

Basheer AL-MOMANI
fuente