Pourquoi utilisons-nous habituellement || plus |? Quelle est la différence?


219

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 &&.


16
La plupart des gens oublient que | est un opérateur booléen non court-circuitant en plus d'être un opérateur au niveau du bit.
John Meagher

1
Les détails sur la différence sont dans le JLS. Voir java.sun.com/docs/books/jls/third_edition/html/…
John Meagher

64
Ils ne sont pas les mêmes. Veuillez consulter les tutoriels à leur sujet, en particulier en ce qui concerne l' évaluation des courts-circuits et l'évaluation avide . ||et &&court-circuit pendant |et &sont impatients.
Hovercraft Full Of Eels

4
Par simple curiosité, dans quel cas voudriez-vous réellement utiliser les versions non court-circuitées? Je vois presque toujours &&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."
Mike Bailey

2
Et, bien sûr, ils ont une priorité différente.
Hot Licks

Réponses:


349

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.

Boolean b = true;
if(b || foo.timeConsumingCall())
{
   //we entered without calling timeConsumingCall()
}

Un autre avantage, comme Jeremy et Peter l'ont mentionné, pour le court-circuit est la vérification de référence nulle:

if(string != null && string.isEmpty())
{
    //we check for string being null before calling isEmpty()
}

Plus d'informations


115
L'exemple canonique estfoo != null && foo.hasBar()
Jeremy

1
Si vous ajoutez une éventuelle exception de référence nulle à l'aide de | du commentaire de @ Jeremy alors c'est une excellente réponse.
Peter Kelly

Souvenez-vous également que && et || signifie une instruction de branche au niveau du code machine (rappelez-vous que les branches peuvent provoquer des erreurs de prédiction), donc si vous êtes super-pédant au sujet des performances, utilisez-les uniquement lorsqu'elles sont réellement requises ( 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.
Jonathan Dickinson

3
Je suis surpris que personne n'ait mentionné quand vous souhaitez utiliser |. Le scénario le plus courant que j'utilise est lorsqu'une variable est modifiée dans la vérification comme (j> 3 | ++ i> 3) ou (++ i> 3 | modifiesGlobalAmongOtherThings () = true). Pas trop commun cependant.
AndSoYouCode

8
Un autre exemple canonique est string == null || string.isEmpty();)
Peter Lawrey

83

| 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.


Donnez une réponse complète et je l'accepterai. Jusqu'à présent, vous êtes le premier à en prendre conscience.
John Meagher

Manque l'aspect bit à bit de |
John Meagher

63

Donc, juste pour construire sur les autres réponses avec un exemple, le court-circuit est crucial dans les contrôles défensifs suivants:

if (foo == null || foo.isClosed()) {
    return;
}

if (bar != null && bar.isBlue()) {
    foo.doSomething();
}

À la place, l' utilisation de |et &pourrait entraîner un NullPointerExceptionjet ici.


Si vous appliquiez le modèle NullObject, il ne le ferait pas (ou plutôt annulerait la réponse). De plus, je dirais que vérifier si le foo est bleu est quelque chose de interne à foo. S'il est bleu, doSomething ne devrait rien faire.
nicodemus13

@ nicodemus13 - de bons points, bien que le motif Null Object ne soit que parfois souhaitable, et le corps pourrait être autre chose qu'un autre appel à foo. "L'exemple canonique" de Peter Lawrey est le meilleur.
Paul Bellora

@Khan: Oui, j'étais plutôt pernicieux et l'objet nul n'est pas toujours adapté. J'ai juste plutôt pris l'habitude de refaçonner inconsciemment les choses. Il n'y a rien de particulièrement mal dans votre réponse.
nicodemus13

39

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:

int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...

Réécrivez-le:

int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i != 10
...

Un autre exemple:

int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...

Réécrivez-le:

int i = 12;
if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement
...

18

Notez également un écueil commun: les opérateurs non paresseux ont priorité sur les paresseux, donc:

boolean a, b, c;
a || b && c; //resolves to a || (b && c)
a | b && c; //resolves to (a | b) && c

Soyez prudent lorsque vous les mélangez.


15

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 & 4est 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 != 0comparaison implicite (pointeurs, flottants, objets avec un operator bool(), etc.) et les opérateurs au niveau du bit sont presque toujours absurdes dans ces contextes.


3
Je suis content qu'au moins quelqu'un mentionné tout le but de l'existence d'opérateurs au niveau du bit.
ulidtko

9

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.


1
Il serait intéressant que le compilateur le fasse automatiquement dans certains cas.
starblue

Peut-être que le JIT le pourrait, mais le compilateur a tendance à ne traiter que des optimisations simples.
Peter Lawrey

2
Oui, j'ai également vu des situations où | est nettement plus rapide que la surcharge de branche de ||, en particulier sur les CPU avec prédiction de branche nulle ou limitée. C'est rare mais pas inconnu. Un de mes collègues est entré dans une guerre de retour dans un code avec un entrepreneur parce qu'il utilisait (correctement) | et l'entrepreneur a continué à penser que c'était "mal".
moelleux

4
@Fluffy, la morale de l'histoire étant que si vous faites quelque chose de délicat, il faut expliquer pourquoi vous avez fait cela ou vos efforts pourraient être gaspillés plus tard. ;)
Peter Lawrey

1
Ouais, il a finalement ajouté un commentaire (à ma suggestion sur la façon de faire en sorte que l'entrepreneur arrête de «le réparer»), et tout va bien.
moelleux

8

|| est l'opérateur logique ou tandis que | est l'opérateur au niveau du bit ou.

boolean a = true;
boolean b = false;

if (a || b) {
}

int a = 0x0001;
a = a | 0x0002;

1
Manque ça | est également un opérateur booléen sans court-circuit.
John Meagher

2
@John Meagher: C'est implicite, car c'est au niveau du bit .
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

@ L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ comment avez-vous rendu votre nom différent dans votre profil?
UdayKiran Pulipati

8

a | b: évaluer b dans tous les cas

a || b: évalue b uniquement si a est évalué à faux


7

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.

 if(something || someotherthing)
 if(something | someotherthing)

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.


Pourquoi voudriez-vous jamais utiliser | dans une instruction if. || est booléen, | n'est pas, | ne serait booléen que si vous travaillez déjà sur deux valeurs booléennes.
FlySwat

Ceci est la première réponse pour tout obtenir.
John Meagher

Cette réponse est incorrecte. Si quelque chose est FAUX, les deux opérateurs passeront à l'opérande suivant. La différence n'apparaît que lorsque le premier opérande est vrai.
Michael Myers

Dommage, il a un exemple absolument ridicule.
FlySwat

Je n'ai aucune idée pourquoi quelqu'un utiliserait | ou & dans une instruction if pour une simple comparaison booléenne, mais c'est parfaitement légal, et j'en ai vu des exemples lorsque j'ai commencé à apprendre la programmation.
Michael Stum

3
| is the binary or operator

|| is the logic or operator

2
Manque ça | est également un opérateur booléen sans court-circuit.
John Meagher

3

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 à booleangauche 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.


Um, |et &sont également des opérateurs conditionnels. Veuillez consulter le lien dans mon commentaire vers le message d'origine.
Aéroglisseur plein d'anguilles

@Hovercraft Full Of Eels: Ce graphique est un peu trompeur; cela fait référence à eux comme des opérateurs conditionnels UNIQUEMENT dans le contexte des valeurs booléennes, où ils sont mathématiquement équivalents à des opérateurs logiques désireux. Lorsque vous commencez à traiter des choses qui ont des valeurs autres que 0 ou 1, ou des valeurs à virgule flottante ou des pointeurs ou autre, la comparaison tombe en panne.
moelleux

@fluffy: il n'y a rien de trompeur sur le graphique puisque la discussion ne portait que sur les opérateurs booléens. Le fait que le |et &puisse être utilisé en tant qu'opérateurs au niveau du bit est un problème complètement différent.
Hovercraft Full Of Eels

1
Il serait plus précis de les désigner comme des opérateurs bit à bit utilisés sur les valeurs booléennes et non comme des opérateurs booléens. Ils ont juste HAPPEN d'être mathématiquement équivalents quand il n'y a qu'un seul bit.
moelleux

2

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.

public static boolean isNotSet(String text) {
   return text == null || text.length() == 0;
}

2

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 avec, 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:

AndExpression:
  EqualityExpression 
  AndExpression & EqualityExpression

ExclusiveOrExpression:
  AndExpression 
  ExclusiveOrExpression ^ AndExpression

InclusiveOrExpression:
  ExclusiveOrExpression 
  InclusiveOrExpression | ExclusiveOrExpression

La syntaxe de EqualityExpressionest définie au § 15.21 , qui nécessite d'être RelationalExpressiondéfinie au § 15.20 , qui à son tour requiert ShiftExpressionet ReferenceTypedéfinie au § 15.19 et au § 4.3 , respectivement. ShiftExpressionrequiert AdditiveExpressiondéfini au §15.18 , qui continue à explorer, en définissant l'arithmétique de base, les opérateurs unaires, etc. ReferenceTypeexplore toutes les différentes façons de représenter un type. (Bien qu'il ReferenceTypen'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 a ReferenceType.)

Les opérateurs binaires et logiques ont les propriétés suivantes:

  • Ces opérateurs ont une priorité différente, avec &la priorité la plus élevée et| la plus la priorité la plus faible.
  • Chacun de ces opérateurs est syntaxiquement associatif à gauche (chaque groupe de gauche à droite).
  • Chaque opérateur est commutatif si les expressions d'opérande n'ont pas d'effets secondaires.
  • Chaque opérateur est associatif.
  • Les opérateurs binaires et logiques peuvent être utilisés pour comparer deux opérandes de type numérique ou deux opérandes de type boolean. Tous les autres cas entraînent une erreur de compilation.

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 booleanou Boolean( §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 longs ou ints 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 booleanou Boolean, les opérandes seront soumis à une conversion de déballage si nécessaire ( §5.1.8 ), et le type de l'opération sera boolean. &entraînera truesi les deux opérandes le sont true, ^entraînera truesi les deux opérandes sont différents et |entraînera truesi l'un des opérandes l'est true. ( §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:

ConditionalAndExpression:
  InclusiveOrExpression 
  ConditionalAndExpression && InclusiveOrExpression

ConditionalOrExpression:
  ConditionalAndExpression 
  ConditionalOrExpression || ConditionalAndExpression

&&est similaire &, sauf qu'il n'évalue l'opérande droit que si l'opérande gauche l'est true. ||est similaire |, sauf qu'il n'évalue l'opérande droit que si l'opérande gauche l'est false.

Conditionnel-Et a les propriétés suivantes:

  • L'opérateur conditionnel et est syntaxiquement associatif à gauche (il regroupe de gauche à droite).
  • L'opérateur conditionnel et est entièrement associatif en ce qui concerne à la fois les effets secondaires et la valeur du résultat. C'est, pour toutes les expressions a, bet c, l' évaluation de l'expression ((a) && (b)) && (c)produit le même résultat, avec les mêmes effets secondaires se produisant dans le même ordre, que l' évaluation de l'expression (a) && ((b) && (c)).
  • Chaque opérande de l'opérateur conditionnel et doit être de type booleanou Boolean, sinon une erreur de compilation se produit.
  • Le type d'une expression conditionnelle et est toujours boolean.
  • Au moment de l'exécution, l'expression d'opérande de gauche est évaluée en premier; si le résultat est de type Boolean, il est soumis à une conversion de déballage ( §5.1.8 ).
  • Si la valeur résultante est false, la valeur de l'expression conditionnelle et est falseet l'expression d'opérande de droite n'est pas évaluée.
  • Si la valeur de l'opérande de gauche est true, alors l'expression de droite est évaluée; si le résultat est de type Boolean, il est soumis à une conversion de déballage ( §5.1.8 ). La valeur résultante devient la valeur de l'expression conditionnelle et.
  • Ainsi, &&calcule le même résultat que &sur les booleanopérandes. Elle ne diffère que par le fait que l'expression d'opérande de droite est évaluée de manière conditionnelle plutôt que toujours.

Conditional-Or a les propriétés suivantes:

  • L'opérateur conditionnel ou est syntaxiquement associatif à gauche (il regroupe de gauche à droite).
  • L'opérateur conditionnel ou est entièrement associatif en ce qui concerne à la fois les effets secondaires et la valeur du résultat. C'est, pour toutes les expressions a, bet c, l' évaluation de l'expression ((a) || (b)) || (c)produit le même résultat, avec les mêmes effets secondaires se produisant dans le même ordre, que l' évaluation de l'expression (a) || ((b) || (c)).
  • Chaque opérande de l'opérateur conditionnel ou doit être de type booleanouBoolean , sinon une erreur de compilation se produit.
  • Le type d'une expression conditionnelle ou est toujours boolean.
  • Au moment de l'exécution, l'expression d'opérande de gauche est évaluée en premier; si le résultat est de type Boolean, il est soumis à une conversion de déballage ( §5.1.8 ).
  • Si la valeur résultante est true, la valeur de l'expression conditionnelle ou est trueet l'expression d'opérande de droite n'est pas évaluée.
  • Si la valeur de l'opérande de gauche est false, alors l'expression de droite est évaluée; si le résultat est de type Boolean, il est soumis à une conversion de déballage ( §5.1.8 ). La valeur résultante devient la valeur de l'expression conditionnelle ou.
  • Ainsi, ||calcule le même résultat que |sur booleanou Booleanopérandes. Elle ne diffère que par le fait que l'expression d'opérande de droite est évaluée de manière conditionnelle plutôt que toujours.

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 soit booleanou Boolean. Avec les bonnes pratiques (ie: pas d'effets secondaires), c'est une différence mineure. Cependant, lorsque les opérandes ne sont pas booleans ou Booleans, 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.


2

1). (Expression1 | expression2), | L'opérateur évaluera expression2, que le résultat de expression1 soit vrai ou faux.

Exemple:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b | test());
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}

2). (Expression1 || expression2), || L'opérateur n'évaluera pas expression2 si expression1 est vraie.

Exemple:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b || test())
        {
            System.out.println("short circuit!");
        }
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}

1

|| renvoie une valeur booléenne en OU deux valeurs (c'est pourquoi son connu comme un LOGIQUE ou)

C'EST À DIRE:

if (A || B) 

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


1

Une différence principale est que || et && présentent un "court-circuit", donc le RHS ne sera évalué que si nécessaire.

Par exemple

if (a || b) {
    path1...
} else {
    path2..
}

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.


1

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:

class foo {

    ArrayList<Bar> list1 = new ArrayList<Bar>();
    ArrayList<Bar> list2 = new ArrayList<Bar>();

    //Returns true if bar is removed from both lists, otherwise false.
    boolean removeBar(Bar bar) {
        return (list1.remove(bar) & list2.remove(bar));
    }
}

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.

//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
    return (list1.remove(bar) && list2.remove(bar));
}

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.


1

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.

int two = -2; int four = -4;
result = two | four; // bitwise OR example

System.out.println(Integer.toBinaryString(two));
System.out.println(Integer.toBinaryString(four));
System.out.println(Integer.toBinaryString(result));

Output:
11111111111111111111111111111110
11111111111111111111111111111100
11111111111111111111111111111110

En savoir plus: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk


Faux lorsque les opérandes sont booléens et formatage stupide.
Marquis de Lorne

2
Cela m'a été utile pour comprendre pourquoi Long.valueOf (100 | 200) = 236. Voici pourquoi: 0 1 1 0 0 1 0 0 | 1 1 0 0 1 0 0 0 = 1 1 1 0 1 1 0 0 = 128 64 32 0 8 4 0 0 = 236
donlys

1

Quand j'ai eu cette question, j'ai créé un code de test pour avoir une idée à ce sujet.

public class HelloWorld{

   public static boolean bool(){
      System.out.println("Bool");
      return true;
   }

   public static void main(String []args){

     boolean a = true;
     boolean b = false;

     if(a||bool())
     {
        System.out.println("If condition executed"); 
     }
     else{
         System.out.println("Else condition executed");
     }

 }
}

Dans ce cas, nous modifions uniquement la valeur de gauche de if si la condition ajoute a ou b.

|| Scénario, lorsque le côté gauche est vrai [if (a || bool ())]

production "If condition executed"

|| Scénario, lorsque le côté gauche est faux [if (b || bool ())]

Production-

Bool
If condition executed

Conclusion of || Lors de l'utilisation ||, le côté droit ne vérifie que lorsque le côté gauche est faux.

| Scénario, lorsque le côté gauche est vrai [if (a | bool ())]

Production-

Bool
If condition executed

| Scénario, lorsque le côté gauche est faux [if (b | bool ())]

Production-

Bool
If condition executed

Conclusion of | Lors de l'utilisation |, vérifiez les côtés gauche et droit.


0

| = au niveau du bit ou, || = logique ou


2
Manque ça | est également un opérateur booléen sans court-circuit.
John Meagher

0

habituellement j'utilise quand il y a un opérateur pré-incrément et post-incrément. Regardez le code suivant:

package ocjpPractice;
/**
 * @author tithik
 *
 */
public class Ex1 {

    public static void main(String[] args) {
    int i=10;
    int j=9;
    int x=10;
    int y=9;
    if(i==10 | ++i>j){
        System.out.println("it will print in first if");  
        System.out.println("i is: "+i);
    }

    if(x==10 ||++x>y){
        System.out.println("it will print in second if");   
        System.out.println("x is: "+x);
    }
    }
}

production:

il imprimera en premier si
i est: 11

il imprimera en deuxième si
x est: 10

les deux ifblocs 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.


1
Je trouve cela très déroutant
NimChimpsky

0

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,

   if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

   private boolean checkIfEmpty(Widget field) {
      if(field.isEmpty()) {
        field.setErrorMessage("Should not be empty!");
        return true;
      }
      return false;
   }

Ainsi, avec l'extrait ci-dessus, si l'utilisateur soumet le formulaire avec TOUS les champs vides, SEUL nameFieldsera affiché avec un message d'erreur. Mais si vous le changez en,

   if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

Il affichera un message d'erreur approprié sur chaque champ, quelles que soient les trueconditions.


0

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ù

if(function1() | function2()){
  ...
}

a dû être changé pour

boolean isChanged = function1();
isChanged |= function2();
if (isChanged){
  ...
}

Quelle est la version réellement acceptée?

La documentation Java n'est pas mentionnée |comme un opérateur OR logique sans court-circuit.

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.





-2

| 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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.