Відповіді:
Із специфікації мови 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()
.