Полагая
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.
Полагая
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
может иметь побочные эффекты; т.е. когда это нетривиальное подвыражение.
Что касается производительности, компромисс между стоимостью оценки 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
вывод b() was called
, поэтому вычисляется правый операнд.
Итак, как уже упоминалось другими, a &= b
- это то же самое, что a = a & b
.
я столкнулся с подобной ситуацией, используя логические значения, где я хотел избежать вызова b(), если a уже было false.
Это сработало для меня:
a &= a && b()