web-dev-qa-db-fra.com

L'opérateur Java & = s'applique-t-il & ou &&&?

En supposant

boolean a = false;

Je me demandais si faire:

a &= b; 

est équivalent à

a = a && b; //logical AND, a is false hence b is not evaluated.

ou d'autre part cela signifie

a = a & b; //Bitwise AND. Both a and b are evaluated.
129
pakore

De la Java - 15.26.2 Opérateurs d'assignation composée .

Une expression d'affectation composée de la forme E1 op= E2 Équivaut à E1 = (T)((E1) op (E2)), où T est le type de E1 , sauf que E1 n’est évalué qu’une fois.

Donc a &= b; Est équivalent à a = a & b;.

(Dans certains cas, la transtypage fait une différence dans le résultat, mais dans celui-ci, b doit être boolean et la transtypage ne fait rien.)

Et, pour mémoire, a &&= b; N'est pas valide en Java. Il n'y a pas d'opérateur &&=.


En pratique, il y a peu de différence entre a = a & b; Et a = a && b;. Si b est une variable ou une constante, le résultat sera le même pour les deux versions. Il n'y a qu'une différence sémantique lorsque l'évaluation de b peut avoir des effets secondaires; c'est-à-dire lorsqu'il s'agit d'une sous-expression non triviale.

Du côté des performances, le compromis est entre le coût de l’évaluation de b, le coût d’un test et d’une branche de la valeur de a, et l’économie potentielle de l’évitement d’une cession inutile. à a. L'analyse n'est pas simple, mais à moins que le coût du calcul de b ne soit pas négligeable, la différence de performances potentielle entre les deux versions risque d'être trop petite pour être prise en compte.

136
Stephen C

voir 15.22.2 du JLS . Pour les opérandes booléens, le & opérateur est booléen, pas au niveau des bits. La seule différence entre && et & pour les opérandes booléens est celui pour && il est court-circuité (ce qui signifie que le second opérande n’est pas évalué si le premier opérande est évalué à false).

Donc dans votre cas, si b est une primitive, a = a && b, a = a & b, et a &= b tous font la même chose.

48
stew

C'est le dernier:

a = a & b;
20
Philippe Leybaert

je suis tombé sur une situation similaire en utilisant des booléens où je voulais éviter d'appeler b() si a était déjà faux.

Cela a fonctionné pour moi:

a &= a && b()
0
Daniel Testa

Voici un moyen simple de le tester:

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;
    }
}

La sortie est b() was called, l'opérande droit est donc évalué.

Ainsi, comme déjà mentionné par d'autres, a &= b Est identique à a = a & b.

0
user7291698