2010-10-11 13 views
106

Suponiendo¿Se aplica el operador Java & = y &&?

boolean a = false; 

me preguntaba si al hacerlo:

a &= b; 

es equivalente a

a = a && b; //logical AND, a is false hence b is not evaluated. 

o por el contrario que significa

a = a & b; //Bitwise AND. Both a and b are evaluated. 

Respuesta

111

A partir de la especificación del lenguaje Java - 15.26.2 Compound Assignment Operators.

Una expresión de asignación compuesto de la forma E1 op= E2 es equivalente a E1 = (T)((E1) op (E2)), donde T es el tipo de E1, excepto que E1 se evalúa sólo una vez.

Así a &= b; es equivalente a a = a & b;.

(En algunos usos, el tipo de fundición hace una diferencia en el resultado, pero en ésta b tiene que ser boolean y el tipo de fundición no hace nada.)


En la práctica, no es poca diferencia entre a = a & b; y a = a && b;. Si b es una variable o una constante, el resultado será el mismo para ambas versiones. Solo hay una diferencia semántica cuando la evaluación de b puede tener efectos secundarios; es decir, cuando es una subexpresión no trivial.

En cuanto al rendimiento, la disyuntiva es entre el costo de la evaluación de b, y el costo de una prueba y rama del valor de a, y el ahorro potencial de evitar una asignación innecesaria a a. El análisis no es directo, pero a menos que el costo de calcular b no sea trivial, la diferencia de rendimiento potencial entre las dos versiones probablemente sea demasiado pequeña para que valga la pena considerarla.

19

Es la última:

a = a & b; 
30

ver 15.22.2 of the JLS. Para operandos booleanos, el operador & es booleano, no bit a bit. La única diferencia entre && y & para operandos booleanos es que para && está en cortocircuito (lo que significa que el segundo operando no se evalúa si el primer operando se evalúa como falso).

Así, en su caso, si b es un primitivo, a = a && b, a = a & b y a &= b todos hacen lo mismo.

+1

Así (un &= b;) se provoque un cortocircuito si b es una llamada de método? ¿Hay algo así como un operador "&& ="? – is7s

+1

correcto. b() se llama. No hay un operador && = – stew

+1

Parece que esto no responde la pregunta; el OP ya sabía sobre cortocircuitos. –

0

encontré una situación similar usando booleanos donde quería evitar llamar a b() si a ya era falso.

Esto funcionó para mí:

a &= a && b() 
+21

Para evitar redundancias (aún permite el cortocircuito), simplemente puede escribir 'a = a && b()'. –