Pourquoi nous avons l'habitude d'utiliser `||` non `|`, quelle est la différence?
Je me demandais simplement pourquoi nous utilisons habituellement la logique OU ||
entre deux booléens pas au niveau du bit OU |
, bien qu'ils travaillent tous les deux bien.
Je veux dire, regardez les suivantes:
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
Peut-on utiliser |
au lieu de ||
? Même chose avec &
et &&
.
- La plupart des gens oublient que | est un non-court-circuit de l'opérateur booléen en plus d'être un opérateur au niveau du bit.
- Les détails sur la différence dans le JLS. Voir java.sun.com/docs/books/jls/third_edition/html/...
- Ils ne sont pas les mêmes. S'il vous plaît consulter les tutoriels sur eux, surtout concernant court-circuit d'évaluation vs désireux d'évaluation.
||
et&&
court-circuit alors que les|
et&
sont impatients. - Juste par curiosité, dans ce cas, vous voulez vraiment utiliser le non court-circuité versions? J'ai presque toujours voir
&&
et||
, mais jamais&
|
. Si vous êtes en train de faire quelque chose qui dépend d'effets secondaires, je ne vois pas pourquoi vous devriez utiliser quelque chose comme(a & b | c)
puisque quelqu'un pourrait facilement penser "je peux optimiser en utilisant la court-circuité versions." - C'est la différence entre (bit à bit) Boolean vs "logique" (c'est à dire, avoir à faire avec les mathématiques "logique"). C'est un peu accessoire (mais très important) que les opérateurs logiques sont "court-circuit".
- Et, bien sûr, ils ont différents priorité.
- Mise à jour JLS lien: docs.oracle.com/javase/specs/jls/se11/html/...
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez le
||
et&&
formes, plutôt que de la|
et&
les formes de ces opérateurs, Java ne sera pas la peine d'évaluer la droite opérande seul.C'est une question de si vous voulez tout court-circuit ou non l'évaluation -- plus du temps que vous souhaitez.
Une bonne façon d'illustrer les avantages de court-circuit serait à considérer l'exemple suivant.
Un autre avantage, comme Jeremy et Peter l'a mentionné, de court-circuit est la référence null check:
plus d'infos
foo != null && foo.hasBar()
foo != null && foo.hasBar()
) ou plus rapide (b || foo.timeConsumingCall()
). 99% des développeurs ne devriez pas avoir à vous soucier de ce niveau de la micro-optimisation des si.string == null || string.isEmpty()
😉Nice Answer
,Enlightened
,Good Answer
,Mortarboard
,Guru
,Great Answer
. Félicitations @Shawn 🙂if(string != null && !string.isEmpty())
, sinon c'est vrai que pour la chaîne vide - pas sûr si c'est ce que vous allez pour les|
ne pas le faire évaluation de court-circuit dans des expressions booléennes.||
va s'arrêter à évaluer si le premier opérande est vrai, mais|
ne sera pas.En outre,
|
peut être utilisé pour effectuer l'opération de bits-OU de l'exploitation sur l'octet/court/int/long valeurs.||
ne peut pas.Donc, il suffit de construire sur l'autre répond avec un exemple, de court-circuit est crucial dans la suite de la défensive des contrôles:
À l'aide de
|
et&
au lieu de cela pourrait entraîner uneNullPointerException
être jeté ici.foo
. Peter Lawrey "l'exemple canonique" est le meilleur.Logique
||
et&&
vérifier le côté droit seulement si nécessaire. Le|
et&
vérifier à la fois les côtés à chaque fois.Par exemple:
Réécrire:
Un autre exemple:
Réécrire:
Également remarquer un piège classique: La non paresseux opérateurs ont la priorité sur les paresseux, donc:
Être prudent lors de les mélanger.
En plus de court-circuit, d'une autre chose à garder à l'esprit est que de faire une opération logique bit à bit sur les valeurs, qui peut être autre que 0 ou 1 a une signification très différente de celle de la logique conditionnelle. Alors qu'il est GÉNÉRALEMENT le même pour
|
et||
, avec&
et&&
vous obtenir des résultats très différents (par exemple,2 & 4
est de 0/false, alors qu'2 && 4
est de 1/vrai).Si la chose que vous obtenez à partir d'une fonction est en fait un code d'erreur et vous faites des tests pour les non-0-ness, ce peut importe beaucoup.
Ce n'est pas un problème en Java où vous devez explicitement transtypage de booléens ou de comparer avec 0 ou similaire, mais dans d'autres langues avec la même syntaxe (C/C++ et al), il peut être assez déroutant.
Notez aussi que & et | peut s'appliquer uniquement de type entier des valeurs, et tout ce qui peut être équivalent à une valeur de type boolean test. Encore une fois, dans la non-Java langues, il y a un certain nombre de choses qui peut être utilisé comme un booléen avec un implicite
!= 0
comparaison (pointeurs, des flotteurs, des objets avec unoperator bool()
, etc.) et les opérateurs sur les bits sont presque toujours absurde dans ces contextes.Le seul moment où vous utiliseriez
|
ou&
au lieu de||
ou&&
, c'est quand vous avez très simple des expressions booléennes et le coût d'une coupe courte (c'est à dire une branche) est plus grand que le temps que vous économisez en n'évaluant pas la plus tard expressions.Cependant, c'est un micro-optimisation de la que rarement, sauf dans le cas le plus faible niveau de code.
|| est l'opérateur logique ou tout | est l'opérateur de bits or.
a | b: évaluer b dans tout cas
a || b: évaluer b seulement si un false
Outre le fait que | est un bit à bit-opérateur: || est un court-circuit à l'opérateur lorsqu'un élément est faux, il ne vérifie pas les autres.
si quelque chose est VRAI, || ne sera pas évaluer someotherthing, tandis que | va faire. Si les variables de votre si-états sont en fait des appels de fonction, à l'aide de || est peut-être sauver une grande partie de la performance.
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.Opérateurs conditionnels ne fonctionne qu'avec des expressions de manière statique évaluer à
boolean
à la fois à gauche et à droite.Opérateurs au niveau du bit fonctionne avec un nombre d'opérandes.
Si vous souhaitez effectuer une comparaison logique, vous devez utiliser opérateurs conditionnels, car vous devrez ajouter un peu de type de type de sécurité de votre code.
|
et&
sont également des opérateurs conditionnels. Veuillez voir le lien dans mon commentaire sur le post original.|
et&
peuvent être utilisés comme des opérateurs bit par bit est une question totalement distincte.Une note de côté: Java a |= mais pas un ||=
Par exemple, si vous devez utiliser || est lors de la première expression est un test pour voir si la deuxième expression ferait exploser. par exemple, à l'Aide d'un seul | dans le cas suivant pourrait entraîner une NPE.
Les autres réponses ont fait un bon travail de couverture de la différence fonctionnelle entre les opérateurs, mais les réponses pourraient s'appliquer à juste au sujet de chaque C dérivé de la langue en existence aujourd'hui. La question est taggés avec java, et donc je m'efforcerai de répondre précisément et techniquement pour le langage Java.
&
et|
peut être soit Entier Opérateurs au niveau du Bit, ou Booléens les Opérateurs Logiques. La syntaxe de l'or au niveau du Bit et d'Opérateurs Logiques (§15.22) est:La syntaxe pour
EqualityExpression
est défini dans §15.21, ce qui nécessiteRelationalExpression
défini dans §15.20, qui à son tour nécessiteShiftExpression
etReferenceType
défini dans §15.19 et §4.3, respectivement.ShiftExpression
nécessiteAdditiveExpression
défini dans §15.18, qui continue à descendre, la définition de l'arithmétique de base, les opérateurs unaires, etc.ReferenceType
dissimulées dans toutes les différentes façons de représenter un type. (Alors queReferenceType
ne comprend pas les types primitifs, la définition de types primitifs est finalement nécessaire, car ils peuvent être le type de dimension pour un tableau, qui est unReferenceType
.)Les Opérateurs Logiques bit à Bit et ont les propriétés suivantes:
La distinction entre l'opérateur sert un bit à bit opérateur ou un opérateur logique dépend si les opérandes sont convertibles à une primitive de type intégral" (§4.2) ou si elles sont de types
boolean
ouBoolean
(§5.1.8).Si les opérandes sont les types intégraux, binaire numérique de promotion (§5.6.2) est effectuée sur les deux opérandes, les laissant à la fois comme
long
s ouint
s pour l'opération. Le type de l'opération sera le type de la (promu) opérandes. À ce point,&
sera au niveau du bit ET,^
seront bit à bit OU exclusif, et|
sera inclusif bit à bit OU. (§15.22.1)Si les opérandes sont
boolean
ouBoolean
, les opérandes seront soumis à l'unboxing de la conversion si nécessaire (§5.1.8), et le type de l'opération seraboolean
.&
entraîneratrue
si les deux opérandes sonttrue
,^
entraîneratrue
si les deux opérandes sont différents, et|
entraîneratrue
si l'un des deux opérandes esttrue
. (§15.22.2)En revanche,
&&
est le "Conditionnel Et de l'Opérateur" (§15.23) et||
est le "Conditionnel Ou de l'Exploitant" (§15.24). Leur syntaxe est définie comme:&&
est comme&
, sauf qu'il n'évalue l'opérande de droite si l'opérande de gauche esttrue
.||
est comme|
, sauf qu'il n'évalue l'opérande de droite si l'opérande de gauche estfalse
.Conditionnel Et a les propriétés suivantes:
Conditionnel Ou a les propriétés suivantes:
En bref, comme @JohnMeagher a souligné à plusieurs reprises dans les commentaires,
&
et|
sont, en fait, non de court-circuiter les opérateurs booléens dans le cas spécifique des opérandes soitboolean
ouBoolean
. Avec de bonnes pratiques (ie: pas d'effets secondaires), c'est une différence mineure. Lorsque les opérandes ne sont pasboolean
s ouBoolean
s, cependant, les opérateurs se comportent très différemment: au niveau du bit et des opérations logiques ne sont tout simplement pas comparables au niveau le plus élevé de la programmation Java.1).(expression1 | expression2), | exploitant d'évaluer expression2, indépendamment de savoir si le résultat de expression1 est vrai ou faux.
Exemple:
2).(expression1 || expression2), || l'opérateur ne sera pas évaluer si les arguments expression1 expression2 est vrai.
Exemple:
|| renvoie une valeur booléenne par OU avec deux valeurs (c'est pourquoi il est connu comme un ou LOGIQUE)
IE:
Serait de retourner vrai si A ou B est vrai, ou faux si ils sont tous les deux faux.
| est un opérateur qui effectue une opération au niveau du bit sur deux valeurs. Afin de mieux comprendre les opérations bit à bit, vous pouvez lire ici:
http://en.wikipedia.org/wiki/Bitwise_operation
Une différence principale est que || et && exposition "court-circuit", donc le membre de droite sera évaluée uniquement si nécessaire.
Pour, par exemple,
Ci-dessus si a est vrai alors b ne sera pas testé et path1 est exécutée. Si | a été ensuite utilisé des deux côtés serait évaluée même si " a " est vrai.
Voir Ici et ici, pour un peu plus d'informations.
Espère que cette aide.
Non court-circuit accidentel peut être utile. Parfois, vous voulez vous assurer que les deux expressions sont évaluées. Par exemple, disons que vous avez une méthode qui supprime un objet à partir de deux listes distinctes. Vous voulez peut-être faire quelque chose comme ceci:
Si votre méthode plutôt utilisé le conditionnel opérande, il ne parviendrait pas à retirer l'objet à partir de la deuxième liste, si la première liste retourné false.
Il n'est pas incroyablement utile, et (comme avec la plupart des tâches de programmation), vous pouvez la réaliser avec d'autres moyens. Mais c'est un cas d'utilisation pour les opérateurs de bits des opérandes.
La différence fondamentale entre les deux est que | convertit les valeurs binaires effectue alors le peu sage ou de l'exploitation. Pendant ce temps, || ne permet pas de convertir les données en binaire et effectue simplement la ou l'expression sur son état d'origine.
Lire la suite: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
Lorsque j'ai eu cette question, j'ai créé un code de test pour se faire une idée à ce sujet.
Dans ce cas, nous ne du changement côté gauche de la valeur de si la condition de l'ajout d'un ou de b.
sortie
"If condition executed"
De sortie-
Conclusion of ||
Lors de l'utilisation||
, du côté droit uniquement à vérifier lorsque la gauche est faux.De sortie-
De sortie-
Conclusion of |
Lors de l'utilisation|
, vérifier à la fois de droite et de gauche.| = ou binaire"/", | | = logique ou
habituellement j'utilise quand il est pré incrémentation et post opérateur d'incrémentation. Regardez le code suivant:
de sortie:
les deux
if
blocs sont les mêmes, mais le résultat est différent.quand il y a
|
, à la fois les conditions seront évaluées. Mais si c'est||
, il ne sera pas évaluer seconde condition que la première condition est déjà le cas.Il existe de nombreux cas d'utilisation suggérant pourquoi devriez-vous aller pour
||
plutôt que|
. Certains cas d'utilisation ont pour utilisation|
opérateur de vérifier toutes les conditions.Par exemple, si vous voulez vérifier la validation d'un formulaire et que vous voulez montrer à l'utilisateur tous les champs non valides avec l'erreur de textes, plutôt que juste un premier champ non valide.
||
opérateur,Donc, avec l'extrait ci-dessus, si l'utilisateur soumet le formulaire avec TOUS les champs vides, SEULEMENT
nameField
serait affiché avec le message d'erreur. Mais, si vous le remplacez,Il va montrer bon message d'erreur sur chaque champ, indépendamment de
true
conditions.|| est un ou logique et | est un peu sage ou.
Java opérateurs
| est ou binaire"/", | | est-ce logique ou la.
Prendre un coup d'oeil à:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
| est inclusif bit à bit OU
|| est logique OU
| est un opérateur au niveau du bit. || est un opérateur logique.
On va prendre deux bits et ou eux.
On va déterminer la vérité (ceci OU cela) Si cela est vrai ou ce qui est vrai, alors la réponse est vrai.
Oh, et dang les gens à répondre à ces questions rapides.