Tout d'abord, quelques antécédents: je suis professeur d'informatique en formation et j'essaie de présenter les opérateurs booléens de java à ma classe de 10e année. Mon enseignant-mentor a examiné une feuille de travail que j'avais préparée et a fait remarquer que je pouvais les laisser utiliser un seul & ou | pour désigner les opérateurs, car ils "font la même chose".
Je suis conscient de la différence entre & et &&.
& est un opérateur au niveau du bit destiné à être utilisé entre des entiers, pour effectuer un "twiddling de bits".
&& est un opérateur conditionnel destiné à être utilisé entre des valeurs booléennes.
Pour prouver que ces opérateurs ne "font pas toujours la même chose", j'ai cherché un exemple où l'utilisation du bit entre les valeurs booléennes conduirait à une erreur. J'ai trouvé cet exemple
boolean bitwise;
boolean conditional;
int i=10, j=12;
bitwise = (i<j) | ((i=3) > 5); // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i<j) || (i=3) > 5 ; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
i=10;
bitwise = (i>j) & (i=3) > 5; // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i>j) && (i=3) > 5; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
Cet exemple montre que si une valeur doit être modifiée par la seconde moitié de l'expression, cela entraînerait une différence entre les résultats, car bitwise est un opérateur impatient, tandis que le conditionnel se comporte comme un court-circuit (n'évalue pas la seconde moitié, si la première moitié est fausse dans le cas de && et vraie dans le cas de ||).
J'ai un problème avec cet exemple. Pourquoi voudriez-vous changer une valeur en même temps que vous faites une comparaison dessus? Cela ne semble pas être un moyen robuste de coder. J'ai toujours été opposé à faire plusieurs opérations sur une seule ligne dans mon code de production. Cela ressemble à quelque chose que ferait un "cowboy codeur" sans conscience quant à la maintenabilité de son code. Je sais que dans certains domaines, le code doit être aussi compact que possible, mais c'est certainement une mauvaise pratique en général?
Je peux expliquer mon choix d'encourager l'utilisation de && et || sur & et | car il s'agit d' une convention de codage acceptée en génie logiciel .
Mais quelqu'un pourrait-il me donner un meilleur exemple, même réel, d'utilisation d'un opérateur au niveau du bit dans une expression conditionnelle?
la source
bitwise = !(true & true == false);
etcondition = !(true && true == false);
tous les deux auront la valeur true, donc dans ce cas ils sont interchangeables? Syntaxiquement peut-être, puisque le code compile toujours. Je conviens qu'ils sont utilisés pour différentes choses sémantiquement, comme je l'ai mentionné au paragraphe 2. Vous dites cela! et & "n'apparaissent presque jamais dans un conditionnel". Je cherche ces cas "presque jamais" et je me demande s'ils existent légitimement.Les opérateurs non binaires
&&
et||
sont des opérateurs de court-circuit. En d'autres termes, avec&&
, si le LHS est faux, le RHS ne sera jamais évalué; avec||
si le LHS est vrai, l'ERS ne sera jamais évaluée. D'un autre côté, les opérateurs au niveau du bit&
et ne|
sont pas en court-circuit, et évalueront toujours à la fois le LHS et le RHS. Sinon, ils sont équivalents dans uneif
déclaration.La seule fois où je peux voir la valeur de l'utilisation des opérateurs non-court-circuit est si le RHS a une sorte d'effet secondaire souhaitable que vous souhaitez voir se produire dans tous les cas. Je ne peux pas penser à un exemple précis où vous voudriez cela, et je ne pense pas que ce soit une bonne pratique, mais c'est la différence.
la source
La réponse philosophique générale est que l'utilisation d'opérateurs au niveau du bit pour les opérateurs booléens est atypique et rend le code plus difficile à lire. En pratique (pour le code en production), un code plus lisible est plus facile à maintenir et donc plus souhaitable.
Pour une utilisation réelle du besoin d'opérateurs de court-circuit, voir des cas tels que:
Ce type d'opérations apparaît fréquemment dans le code du monde réel.
la source
&
est «plus difficile à lire» que 2? Je n'ai pas d'exemple dans lequel les 2 opérateurs ne fonctionnent pas de la même manière pour les opérandes booléens. Je suis d'accord sur votre point concernant le code plus lisible et plus facile à maintenir. Je veux les encourager à écrire du beau code. Mais avoir des preuves dans mon sac d'outils serait plus convaincant que «parce que je l'ai dit». Je l'ai indiqué comme norme à ce lien, et je devrai peut-être m'en remettre à cela uniquement si je ne reçois pas l'exemple que je recherche. Comme je l'ai demandé à @Steve Haigh: Java devrait-il indiquer cela comme une mauvaise utilisation?Vous utiliserez des opérateurs au niveau du bit si vous comparez les énumérations Bitmask. Par exemple, vous disposez d'une énumération d'états et d'un objet qui peut se trouver dans plusieurs de ces états. Dans ce cas, vous devrez faire un bit à bit ou assigner plus d'un état à votre objet.
par exemple
state = CONNECTED | IN_PROGRESS
oùCONNECTED could be 0x00000001
etIN_PROGRESS 0x00000010
Pour plus d'informations, consultez la documentation des énumérations d'indicateurs.
la source
un exemple plus simple de tort:
ici, vous avez deux conditions, les deux sont non nulles; mais le bit à bit
&
résultat au niveau est nul.la source
(condA && condB)
des erreurs, car le && ne fonctionne pas pendant 2int
s, seulement 2 booléens.(condA & condB)
bien que correct, évalue à unint
et en java, nous ne pouvons pas le direif(int)
, il se trompe aussi. Vous êtes le premier à comprendre ce que je recherche cependant - exactement cet exemple de mal .(Boolean(condA) && Boolean(condB))
(je pense queBoolean(x)
c'esttrue
pour des entiers non nuls, non?)((condA!=0) && (condB!=0))
?if (((condA!=0) && (condB!=0))) { System.out.println("correct"); } if (((condA!=0) & (condB!=0))) { System.out.println("never executed?"); }
exécute les deux instructions d'impression.