Respostas:
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 aE1 = (T)((E1) op (E2))
, ondeT
é o tipo deE1
, exceto queE1
é 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 b
deve ser boolean
e 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 b
for uma variável ou uma constante, o resultado será o mesmo para as duas versões. Existe apenas uma diferença semântica quando b
uma 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 b
e 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 b
não seja trivial, a diferença de desempenho entre as duas versões é muito pequena para ser considerada.
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 & b
e a &= b
todos fazem a mesma coisa.
É o último:
a = a & b;
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
.
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()
a=a&&b()
.