O operador Java & = aplica & ou &&?

139

Assumindo

boolean a = false;

Eu queria saber se está fazendo:

a &= b; 

é equivalente a

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

ou por outro lado, isso significa

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

Respostas:

146

Na especificação da linguagem Java - 15.26.2 Operadores de atribuição composta .

Uma expressão de atribuição composta do formulário E1 op= E2é equivalente a E1 = (T)((E1) op (E2)), onde Té o tipo de E1, exceto que E1é avaliada apenas uma vez.

Então a &= b;é equivalente aa = a & b; .

(Em alguns usos, a conversão de tipo faz diferença no resultado, mas nesse caso bdeve ser booleane a conversão de tipo não faz nada.)

E, para o registro, a &&= b;não é Java válido. Não há &&=operador.


Na prática, há pouca diferença semântica entre a = a & b;e a = a && b;. (Se bfor uma variável ou uma constante, o resultado será o mesmo para as duas versões. Existe apenas uma diferença semântica quando buma subexpressão com efeitos colaterais. No &caso, o efeito colateral sempre ocorre. &&caso isso ocorra, dependendo do valor de a.)

No lado do desempenho, o trade-off está entre o custo da avaliação be o custo de um teste e ramo do valor de a, e a economia potencial de evitar uma atribuição desnecessária a. A análise não é direta, mas, a menos que o custo do cálculo bnão seja trivial, a diferença de desempenho entre as duas versões é muito pequena para ser considerada.

Stephen C
fonte
Seu parágrafo "na prática" é enganoso. O único motivo para usar & over && é calcular subexpressão não trivial em "b"
AlexP
Esclarecido. (De fato, a trivialidade realmente não entra nisso.)
Stephen C
51

ver 15.22.2 do JLS . Para operandos booleanos, o &operador é booleano, não bit a bit. A única diferença entre &&e &para operandos booleanos é que, devido &&a um curto-circuito (o que significa que o segundo operando não é avaliado se o primeiro operando for falso).

Assim, no seu caso, se bé um, primitivo a = a && b, a = a & be a &= btodos fazem a mesma coisa.

ensopado
fonte
2
Então (a & = b;) não entrará em curto-circuito se b for uma chamada de método? existe algo como um operador "&& ="?
Is7s
2
Parece que isso não responde à pergunta; o OP já sabia sobre curtos-circuitos.
OR # Mapper
21

É o último:

a = a & b;
Philippe Leybaert
fonte
0

Aqui está uma maneira simples de testá-lo:

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;
    }
}

A saída é b() was called , portanto, o operando do lado direito é avaliado.

Então, como já mencionado por outros, a &= bé o mesmo que a = a & b.

user7291698
fonte
-2

Me deparei com uma situação semelhante usando booleanos, onde eu queria evitar chamar b () se a já fosse falso.

Isso funcionou para mim:

a &= a && b()
Daniel Testa
fonte
25
Para evitar redundâncias (ainda permitindo curto-circuito), você pode simplesmente escrever a=a&&b().
Unai Vivi