Предполагая
boolean a = false;
Мне было интересно, делал ли:
a &= b;
эквивалентно
a = a && b; //logical AND, a is false hence b is not evaluated.
или с другой стороны это означает
a = a & b; //Bitwise AND. Both a and b are evaluated.
Ответы:
Из Спецификации языка Java - 15.26.2 Операторы составного присваивания .
Составное выражение присваивания формы
E1 op= E2эквивалентноE1 = (T)((E1) op (E2)), гдеT- типE1, за исключением того, чтоE1оно оценивается только один раз.
Так a &= b;эквивалентно a = a & b;.
(В некоторых случаях приведение типов имеет значение для результата, но в этом bслучае booleanприведение типов должно быть таким, и приведение типов ничего не делает.)
И, к сведению, a &&= b;недопустима Java. Нет &&=оператора.
На практике существует небольшая семантическая разница между a = a & b;и a = a && b;. (Если bэто переменная или константа, результат будет одинаковым для обеих версий. Семантическая разница существует только в bтом &случае, если подвыражение имеет побочные эффекты. В этом случае побочный эффект возникает всегда. &&случается в зависимости от значения a.)
Что касается производительности, компромисс между стоимостью оценки bи стоимостью теста и перехода значения a, а также потенциальной экономией за счет избежания ненужного присвоения a. Анализ не является прямым, но если стоимость вычислений не bявляется нетривиальной, разница в производительности между двумя версиями слишком мала, чтобы ее стоило учитывать.
см. 15.22.2 JLS . Для булевых операндов &оператор является логическим, а не побитовым. Единственная разница между логическими операндами &&и &для них заключается в том, что &&они закорочены (это означает, что второй операнд не оценивается, если первый операнд принимает значение false).
Так что в вашем случае, если bэто примитивно, a = a && b, a = a & bи a &= bвсе делают то же самое.
Это последний:
a = a & b;
Вот простой способ проверить это:
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;
}
}
Выходной сигнал равен b() was called, поэтому оценивается правый операнд.
Итак, как уже упоминалось другими, a &= bэто то же самое, что и a = a & b.
Я столкнулся с аналогичной ситуацией с использованием логических значений, когда я хотел избежать вызова b (), если a уже было ложным.
Это сработало для меня:
a &= a && b()
a=a&&b().