Используется ли оператор Java & = & или &&?

Полагая

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.

Ответ 1

Из спецификации языка 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 нетривиальна, различие в потенциальной производительности между двумя версиями, вероятно, будет слишком маленьким, чтобы его стоило учитывать.

Ответ 2

см. 15.22.2 JLS. Для булевых операндов оператор & является логическим, а не побитовым. Единственное различие между && и & для булевых операндов заключается в том, что для && оно короткое замыкание (это означает, что второй операнд не оценивается, если первый операнд имеет значение false).

Итак, в вашем случае, если b является примитивным, a = a && b, a = a & b и a &= b все делают то же самое.

Ответ 3

Это последнее:

a = a & b;

Ответ 4

Вот простой способ проверить это:

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.

Ответ 5

я столкнулся с подобной ситуацией, используя логические значения, где я хотел избежать вызова b(), если a уже было false.

Это сработало для меня:

a &= a && b()