127 votes

Effet d'un opérateur binaire sur un booléen en Java

Les opérateurs bit à bit sont censés parcourir des variables et opérer sur elles bit par bit. Dans le cas des entiers, des longs, des caractères, cela a du sens. Ces variables peuvent contenir toute la gamme de valeurs imposées par leur taille.

Dans le cas des booléens, cependant, un booléen ne peut contenir que deux valeurs. 1 = vrai ou 0 = faux. Mais la taille du booléen n'est pas définie. Il peut être aussi grand qu'un octet ou aussi petit qu'un bit.

Quel est l'effet de l'utilisation d'un opérateur binaire sur un booléen ? La JVM le transforme-t-elle en un opérateur logique normal et continue-t-elle ? Traite-t-elle le booléen comme une entité à un seul bit pour les besoins de l'opération ? Ou bien le résultat est-il indéfini, tout comme la taille d'un booléen ?

1 votes

Je pense que l'on ne peut pas utiliser un opérateur bitwise sur un booléen. Seulement sur les nombres. Je suis sûr que ~ ne fonctionnera pas, je ne sais pas ce qu'il en est des autres opérateurs.

4 votes

Vous pouvez utiliser certains d'entre eux, nous venons de découvrir un | utilisé dans notre ancien code. Nous allons le supprimer, mais ce code a été compilé et a fonctionné.

9 votes

Puisque l'un court-circuite et l'autre pas (voir la réponse de mobrule), avant de changer le | en ||, vous pouvez vous assurer que les expressions booléennes suivantes n'ont pas d'effets secondaires que le programmeur original avait l'intention de toujours exécuter.

129voto

Noel Ang Points 1991

Les opérateurs & , ^ y | sont des opérateurs binaires lorsque les opérandes sont des types intégraux primitifs. Ce sont des opérateurs logiques lorsque les opérandes sont booléens, et leur comportement dans ce dernier cas est spécifié. Voir la section 15.22.2 de la norme Spécification du langage Java pour les détails.

63 votes

Plus précisément, & et ^ et | sont les opérateurs booléens logiques non court-circuités.

0 votes

Si ce qui précède est vrai, pourquoi ideone.com/oGSF7c en lançant une exception de pointeur nul ? Si le |= était logique, le programme n'aurait jamais dû exécuter l'opérateur x.getValue() directive.

1 votes

@JohnKrommidas, votre x est nul, c'est pourquoi vous obtenez une NullPointerException. Vous devez l'instancier.

95voto

mob Points 61524

L'utilisation de l'opérateur bit à bit peut contourner le comportement de court-circuitage :

boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();

Si booleanExpression1() évalue à false alors
booleanExpression2() n'est pas évalué dans le premier cas, et
booleanExpression2() (et les effets secondaires qu'elle peut avoir) est évaluée dans le second cas,

2 votes

Et l'opération par bit exécute habituellement plus rapide que celle du court-circuit (à condition que l'évaluation soit simple)

1 votes

La méthode bit à bit & sera plus rapide, mais l'appel à la seconde fonction pourrait être ignoré avec l'utilisation de la fonction &&

21voto

Dukeling Points 31203

Au-delà de ce qui est couvert dans les autres réponses, il convient de noter que && y || ont une préséance différente de celle des & y | .

Extrait de le tableau de préséance (avec la plus haute priorité en haut).

bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||

Qu'est-ce que cela signifie pour vous ?

Absolument rien, tant que vous vous en tenez à l'un ou l'autre de ces deux éléments. & y | ou seulement && y || .

Mais, comme | a une plus grande précendance que && (par opposition à || qui a une priorité inférieure), les mélanger librement pourrait conduire à un comportement inattendu.

Alors a && b | c && d est la même chose que a && (b | c) && d ,
à l'opposé de a && b || c && d qui serait (a && b) || (c && d) .

Pour prouver que ce n'est pas la même chose, considérons un extrait de la table de vérité :

a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T |   T   |   F    |    T   |         F       |        T
                                                  ^                ^
                                                  |- not the same -|

Si vous voulez que OR ait une plus grande priorité que AND, vous devez pourrait utiliser | y && ensemble, mais ce n'est pas recommandé.

Mais vous devriez vraiment les mettre entre parenthèses pour clarifier la préséance lorsque vous utilisez différents symboles, par ex. (a && b) || c (entre parenthèses pour clarifier la préséance), a && b && c (pas de parenthèses nécessaires).

4voto

LeffeBrune Points 1474

Même si ça marche, tu ne devrais pas le faire. Les spécifications du langage définissent les opérateurs bitwise uniquement lorsque les deux opérandes sont de type entier primitif ou de type booléen. Je dirais que pour tout autre cas, les résultats ne sont pas définis :

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228

0 votes

La question est sur les booléens, et non sur les primitives ou un mélange de primitives et de booléens.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X