Je me demande simplement pourquoi nous utilisons habituellement un OU logique ||
entre deux booléens qui ne sont pas des bits OU |
, bien qu'ils fonctionnent tous les deux bien.
Je veux dire, regardez ce qui suit:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
Pouvons-nous utiliser à la |
place de ||
? Même chose avec &
et &&
.
java
bitwise-operators
Eng.Fouad
la source
la source
||
et&&
court-circuit pendant|
et&
sont impatients.&&
et||
, mais jamais&
|
. Si vous faites quelque chose qui dépend des effets secondaires, je ne vois pas pourquoi vous utiliseriez quelque chose comme,(a & b | c)
car quelqu'un pourrait facilement penser "Je peux optimiser cela en utilisant les versions en court-circuit."Réponses:
Si vous utilisez les formulaires
||
et&&
, plutôt que les formulaires|
et&
de ces opérateurs, Java ne prendra pas la peine d'évaluer seul l'opérande de droite.Il s'agit de savoir si vous voulez court-circuiter l'évaluation ou non - la plupart du temps vous le souhaitez.
Un bon moyen d'illustrer les avantages du court-circuit serait de considérer l'exemple suivant.
Un autre avantage, comme Jeremy et Peter l'ont mentionné, pour le court-circuit est la vérification de référence nulle:
Plus d'informations
la source
foo != null && foo.hasBar()
foo != null && foo.hasBar()
) ou plus rapides (b || foo.timeConsumingCall()
). 99% des développeurs ne devraient cependant pas avoir à se soucier de ce niveau de micro-optimisation.string == null || string.isEmpty()
;)|
ne fait pas d' évaluation de court-circuit dans les expressions booléennes.||
arrêtera d'évaluer si le premier opérande est vrai, mais|
ne le sera pas.De plus,
|
peut être utilisé pour effectuer l'opération OR au niveau du bit sur des valeurs d'octet / court / int / long.||
ne peux pas.la source
Donc, juste pour construire sur les autres réponses avec un exemple, le court-circuit est crucial dans les contrôles défensifs suivants:
À la place, l' utilisation de
|
et&
pourrait entraîner unNullPointerException
jet ici.la source
foo
. "L'exemple canonique" de Peter Lawrey est le meilleur.Logique
||
et&&
vérifiez le côté droit uniquement si nécessaire. Le|
et&
vérifier à la fois les côtés à chaque fois .Par exemple:
Réécrivez-le:
Un autre exemple:
Réécrivez-le:
la source
Notez également un écueil commun: les opérateurs non paresseux ont priorité sur les paresseux, donc:
Soyez prudent lorsque vous les mélangez.
la source
En plus du court-circuit, une autre chose à garder à l'esprit est que faire une opération logique au niveau du bit sur des valeurs qui peuvent être différentes de 0 ou 1 a une signification très différente de la logique conditionnelle. Bien que ce soit généralement le même pour
|
et||
, avec&
et&&
vous obtenez des résultats très différents (par exemple,2 & 4
est 0 / faux pendant2 && 4
est 1 / vrai).Si la chose que vous obtenez d'une fonction est en fait un code d'erreur et que vous testez la non-0-ness, cela peut avoir beaucoup d'importance.
Ce n'est pas autant un problème en Java où vous devez explicitement transtyper en booléen ou comparer avec 0 ou similaire, mais dans d'autres langages avec une syntaxe similaire (C / C ++ et al), cela peut être assez déroutant.
Notez également que & et | ne peut s'appliquer qu'aux valeurs de type entier et non à tout ce qui peut être équivalent à un test booléen. Encore une fois, dans les langages non Java, il y a pas mal de choses qui peuvent être utilisées comme un booléen avec une
!= 0
comparaison implicite (pointeurs, flottants, objets avec unoperator bool()
, etc.) et les opérateurs au niveau du bit sont presque toujours absurdes dans ces contextes.la source
La seule fois où vous utiliseriez
|
ou à la&
place de||
ou&&
c'est lorsque vous avez des expressions booléennes très simples et que le coût d'un raccourci (c'est-à-dire une branche) est supérieur au temps que vous économisez en n'évaluant pas les expressions les plus récentes.Cependant, il s'agit d'une micro-optimisation qui compte rarement sauf dans le code le plus bas.
la source
|| est l'opérateur logique ou tandis que | est l'opérateur au niveau du bit ou.
la source
a | b: évaluer b dans tous les cas
a || b: évalue b uniquement si a est évalué à faux
la source
En plus du fait que | est un opérateur au niveau du bit: || est un opérateur de court-circuit - lorsqu'un élément est faux, il ne vérifie pas les autres.
si quelque chose est VRAI, || n'évaluera pas autre chose, alors que | ça ira. Si les variables de vos instructions if sont en fait des appels de fonction, utilisez || économise peut-être beaucoup de performances.
la source
la source
Les opérateurs
||
et&&
sont appelés opérateurs conditionnels , tandis que|
et&
sont appelés opérateurs au niveau du bit . Ils servent à des fins différentes.Les opérateurs conditionnels ne fonctionnent qu'avec des expressions qui sont évaluées statiquement à
boolean
gauche et à droite.Les opérateurs au niveau du bit fonctionnent avec tous les opérandes numériques.
Si vous souhaitez effectuer une comparaison logique, vous devez utiliser des opérateurs conditionnels , car vous ajouterez une sorte de sécurité de type à votre code.
la source
|
et&
sont également des opérateurs conditionnels. Veuillez consulter le lien dans mon commentaire vers le message d'origine.|
et&
puisse être utilisé en tant qu'opérateurs au niveau du bit est un problème complètement différent.Une note latérale: Java a | = mais pas un || =
Un exemple de quand vous devez utiliser || c'est quand la première expression est un test pour voir si la deuxième expression exploserait. par exemple en utilisant un seul | dans le cas suivant, il pourrait en résulter un NPE.
la source
Les autres réponses ont fait un bon travail pour couvrir la différence fonctionnelle entre les opérateurs, mais les réponses pourraient s'appliquer à à peu près tous les langages dérivés de C existants aujourd'hui. La question est étiquetée avecJava, et donc je m'efforcerai de répondre spécifiquement et techniquement au langage Java.
&
et|
peut être soit des opérateurs binaires entiers, soit des opérateurs logiques booléens. La syntaxe des opérateurs binaires et logiques ( §15.22 ) est:La syntaxe de
EqualityExpression
est définie au § 15.21 , qui nécessite d'êtreRelationalExpression
définie au § 15.20 , qui à son tour requiertShiftExpression
etReferenceType
définie au § 15.19 et au § 4.3 , respectivement.ShiftExpression
requiertAdditiveExpression
défini au §15.18 , qui continue à explorer, en définissant l'arithmétique de base, les opérateurs unaires, etc.ReferenceType
explore toutes les différentes façons de représenter un type. (Bien qu'ilReferenceType
n'inclue pas les types primitifs, la définition des types primitifs est finalement requise, car ils peuvent être le type de dimension pour un tableau, qui est aReferenceType
.)Les opérateurs binaires et logiques ont les propriétés suivantes:
La distinction entre si l'opérateur sert d'opérateur au niveau du bit ou d'opérateur logique dépend du fait que les opérandes sont "convertibles en un type intégral primitif" ( §4.2 ) ou s'ils sont de types
boolean
ouBoolean
( §5.1.8 ).Si les opérandes sont de type intégral, une promotion numérique binaire ( §5.6.2 ) est effectuée sur les deux opérandes, en les laissant tous les deux comme
long
s ouint
s pour l'opération. Le type de l'opération sera le type des opérandes (promus). À ce stade,&
sera ET au niveau du bit,^
sera OU exclusif au niveau du bit et|
sera OU inclus au niveau du bit. ( §15.22.1 )Si les opérandes sont
boolean
ouBoolean
, les opérandes seront soumis à une conversion de déballage si nécessaire ( §5.1.8 ), et le type de l'opération seraboolean
.&
entraîneratrue
si les deux opérandes le sonttrue
,^
entraîneratrue
si les deux opérandes sont différents et|
entraîneratrue
si l'un des opérandes l'esttrue
. ( §15.22.2 )En revanche,
&&
est le "Conditional-And Operator" ( §15.23 ) et||
est le "Conditional-Or Operator" ( §15.24 ). Leur syntaxe est définie comme:&&
est similaire&
, sauf qu'il n'évalue l'opérande droit que si l'opérande gauche l'esttrue
.||
est similaire|
, sauf qu'il n'évalue l'opérande droit que si l'opérande gauche l'estfalse
.Conditionnel-Et a les propriétés suivantes:
Conditional-Or a les propriétés suivantes:
En bref, comme @JohnMeagher l'a souligné à plusieurs reprises dans les commentaires,
&
et|
sont en fait des opérateurs booléens ne court-circuitant pas dans le cas spécifique des opérandes étant soitboolean
ouBoolean
. Avec les bonnes pratiques (ie: pas d'effets secondaires), c'est une différence mineure. Cependant, lorsque les opérandes ne sont pasboolean
s ouBoolean
s, les opérateurs se comportent très différemment: les opérations au niveau du bit et logiques ne se comparent tout simplement pas bien au niveau élevé de la programmation Java.la source
1). (Expression1 | expression2), | L'opérateur évaluera expression2, que le résultat de expression1 soit vrai ou faux.
Exemple:
2). (Expression1 || expression2), || L'opérateur n'évaluera pas expression2 si expression1 est vraie.
Exemple:
la source
|| renvoie une valeur booléenne en OU deux valeurs (c'est pourquoi son connu comme un LOGIQUE ou)
C'EST À DIRE:
Renvoie vrai si A ou B est vrai, ou faux si les deux sont faux.
| est un opérateur qui effectue une opération au niveau du bit sur deux valeurs. Pour mieux comprendre les opérations au niveau du bit, vous pouvez lire ici:
http://en.wikipedia.org/wiki/Bitwise_operation
la source
Une différence principale est que || et && présentent un "court-circuit", donc le RHS ne sera évalué que si nécessaire.
Par exemple
Au-dessus, si a est vrai, b ne sera pas testé et path1 sera exécuté. Si | a été utilisé, les deux côtés seraient évalués même si «a» est vrai.
Voir ici et ici , pour un peu plus d'informations.
J'espère que cela t'aides.
la source
La non mise en court-circuit peut être utile. Parfois, vous voulez vous assurer que deux expressions sont évaluées. Par exemple, supposons que vous ayez une méthode qui supprime un objet de deux listes distinctes. Vous voudrez peut-être faire quelque chose comme ceci:
Si votre méthode utilisait à la place l'opérande conditionnelle, elle ne parviendrait pas à supprimer l'objet de la deuxième liste si la première liste renvoyait false.
Ce n'est pas incroyablement utile, et (comme pour la plupart des tâches de programmation), vous pouvez le réaliser avec d'autres moyens. Mais c'est un cas d'utilisation pour les opérandes au niveau du bit.
la source
La différence fondamentale entre eux est que | convertit d'abord les valeurs en binaire puis effectue l'opération ou le bit. Pendant ce temps, || ne convertit pas les données en binaire et exécute simplement l'expression or sur son état d'origine.
En savoir plus: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
la source
Quand j'ai eu cette question, j'ai créé un code de test pour avoir une idée à ce sujet.
Dans ce cas, nous modifions uniquement la valeur de gauche de if si la condition ajoute a ou b.
production
"If condition executed"
Production-
Conclusion of ||
Lors de l'utilisation||
, le côté droit ne vérifie que lorsque le côté gauche est faux.Production-
Production-
Conclusion of |
Lors de l'utilisation|
, vérifiez les côtés gauche et droit.la source
| = au niveau du bit ou, || = logique ou
la source
habituellement j'utilise quand il y a un opérateur pré-incrément et post-incrément. Regardez le code suivant:
production:
les deux
if
blocs sont identiques mais le résultat est différent. quand il y en a|
, les deux conditions seront évaluées. Mais si c'est le cas||
, il n'évaluera pas la deuxième condition car la première condition est déjà vraie.la source
Il existe de nombreux cas d'utilisation suggérant pourquoi vous devriez y aller
||
plutôt que|
. Certains cas d' utilisation doivent utiliser|
opérateur pour vérifier toutes les conditions.Par exemple, si vous souhaitez vérifier la validation du formulaire et que vous souhaitez montrer à l'utilisateur tous les champs non valides avec des textes d'erreur plutôt qu'un seul premier champ non valide.
||
l'opérateur serait,Ainsi, avec l'extrait ci-dessus, si l'utilisateur soumet le formulaire avec TOUS les champs vides, SEUL
nameField
sera affiché avec un message d'erreur. Mais si vous le changez en,Il affichera un message d'erreur approprié sur chaque champ, quelles que soient les
true
conditions.la source
Après avoir lu attentivement ce sujet, je ne sais toujours pas si vous utilisez
|
tant qu'opérateur logique est conforme aux pratiques de modèle Java.J'ai récemment modifié le code dans une demande de tirage adressant un commentaire où
a dû être changé pour
Quelle est la version réellement acceptée?
Pas intéressé par un vote mais plutôt par la recherche de la norme?! Les deux versions de code se compilent et fonctionnent comme prévu.
la source
|| est un ou logique et | est un peu sage ou.
la source
Opérateurs Java
| est au niveau du bit ou, || est logique ou.
la source
Jeter un coup d'œil à:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
| est inclus au niveau du bit OU
|| est logique OU
la source
| est un opérateur au niveau du bit. || est un opérateur logique.
On prendra deux bits et / ou eux.
On déterminera la vérité (ceci OU cela) Si c'est vrai ou cela est vrai, alors la réponse est vraie.
Oh, et les gens dang répondent rapidement à ces questions.
la source