¿El operador Java & = aplica & o &&?


139

Asumiendo

boolean a = false;

Me preguntaba si hacer:

a &= b; 

es equivalente a

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

o por otro lado significa

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

Respuestas:


146

De la especificación del lenguaje Java - 15.26.2 Operadores de asignación compuesta .

Una expresión de asignación compuesta de la forma E1 op= E2es equivalente a E1 = (T)((E1) op (E2)), donde Tes el tipo de E1, excepto que E1se evalúa solo una vez.

Entonces a &= b;es equivalente a a = a & b;.

(En algunos usos, la conversión de tipos marca una diferencia en el resultado, pero en este btiene que ser booleany la conversión de tipos no hace nada).

Y, para el registro, a &&= b;no es válido Java. No hay &&=operador


En la práctica, hay poca diferencia semántica entre a = a & b;y a = a && b;. (Si bes una variable o una constante, el resultado será el mismo para ambas versiones. Solo hay una diferencia semántica cuando bhay una subexpresión que tiene efectos secundarios. En el &caso, el efecto secundario siempre ocurre. &&caso ocurre dependiendo del valor de a.)

Por el lado del rendimiento, la compensación es entre el costo de la evaluación by el costo de una prueba y una rama del valor de a, y el ahorro potencial de evitar una asignación innecesaria a a. El análisis no es sencillo, pero a menos que el costo de calcular bno sea trivial, la diferencia de rendimiento entre las dos versiones es demasiado pequeña para que valga la pena considerarla.


Su párrafo "en la práctica" es engañoso. La única razón para usar & over && es calcular la subexpresión no trivial en "b"
AlexP

Aclarado (De hecho, la trivialidad realmente no entra en juego.)
Stephen C

51

ver 15.22.2 del JLS . Para operandos booleanos, el &operador es booleano, no bit a bit. La única diferencia entre &&y &para los operandos booleanos es que &&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 bes una, primitivo a = a && b, a = a & by a &= btodos hacen lo mismo.


2
Entonces (a & = b;) no se cortocircuitará si b es una llamada al método? ¿hay algo como un operador "&& ="?
is7s

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


0

Aquí hay una manera simple de probarlo:

public class OperatorTest {     
    public static void main(String[] args) {
        boolean a = false;
        a &= b();
    }

    private static boolean b() {
        System.out.println("b() was called");
        return true;
    }
}

La salida es b() was called, por lo tanto, se evalúa el operando de la derecha.

Entonces, como ya lo mencionaron otros, a &= bes lo mismo que a = a & b.


-2

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()

25
Para evitar redundancias (aún permitiendo cortocircuitos), simplemente puede escribir a=a&&b().
Unai Vivi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.