Відповіді:
Із специфікації мови 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 . Для булевих операндів &оператор булів, а не порозрядно. Єдина відмінність між &&та &булевими операндами полягає в тому, що для &&нього коротке замикання (це означає, що другий операнд не оцінюється, якщо перший операнд оцінюється як хибний).
Так що в вашому випадку, якщо 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().