web-dev-qa-db-fra.com

Java opérateur logique court-circuitant

Quel ensemble est en court-circuit et qu'est-ce que cela signifie exactement que l'expression conditionnelle complexe est en court-circuit?

public static void main(String[] args) {
  int x, y, z;

  x = 10;
  y = 20;
  z = 30;

  // T T
  // T F
  // F T
  // F F

  //SET A
  boolean a = (x < z) && (x == x);
  boolean b = (x < z) && (x == z);
  boolean c = (x == z) && (x < z);
  boolean d = (x == z) && (x > z);
  //SET B    
  boolean aa = (x < z) & (x == x);
  boolean bb = (x < z) & (x == z);
  boolean cc = (x == z) & (x < z);
  boolean dd = (x == z) & (x > z);

}
88
Aaron

Le && et || opérateurs "court-circuit", ce qui signifie qu'ils n'évaluent pas le côté droit si ce n'est pas nécessaire.

Le & et | les opérateurs, lorsqu'ils sont utilisés comme opérateurs logiques, évaluent toujours les deux côtés.

Il n'y a qu'un seul cas de court-circuit pour chaque opérateur, et ils sont:

  • false && ... _ - il n'est pas nécessaire de connaître le côté droit, le résultat doit être false
  • true || ... _ - il n'est pas nécessaire de connaître le côté droit, le résultat doit être true

Comparons le comportement dans un exemple simple:

public boolean longerThan(String input, int length) {
    return input != null && input.length() > length;
}

public boolean longerThan(String input, int length) {
    return input != null & input.length() > length;
}

La 2ème version utilise l'opérateur sans court-circuit & et jettera un NullPointerException si input est null, mais la première version retournera false sans exception;

220
Bohemian

SET A utilise des opérateurs booléens en court-circuit.

Dans le contexte des opérateurs booléens, le terme "court-circuit" signifie que, pour un ensemble de booléens b1, b2, ..., bn, les versions de court-circuit cesseront d'être évaluées dès que le premier de ces booléens sera vrai (|| ) ou fausses (&&).

Par exemple:

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)

// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)
9
afrischke

En clair, court-circuiter signifie arrêter l’évaluation une fois que vous savez que la réponse ne peut plus changer. Par exemple, si vous évaluez une chaîne de ANDs logiques et que vous découvrez un FALSE au milieu de cette chaîne, vous savez que le résultat sera faux, quelles que soient les valeurs. du reste des expressions de la chaîne. Il en va de même pour une chaîne de ORs: une fois que vous avez découvert un TRUE, vous connaissez la réponse tout de suite et vous pouvez donc ignorer l'évaluation du reste des expressions.

Vous indiquez à Java que vous souhaitez court-circuiter en utilisant && au lieu de & et || au lieu de |. La première série de votre message est un court-circuit.

Notez qu’il s’agit bien plus que de sauver quelques cycles de la CPU:

if (mystring != null && mystring.indexOf('+') > 0) {
    ...
}

court-circuiter signifie une différence entre un fonctionnement correct et un plantage (dans le cas où la mystérieuse est nulle).

4
dasblinkenlight
boolean a = (x < z) && (x == x);

Ce genre va court-circuiter, ce qui signifie que si (x < z) évalue à false, le dernier n’est pas évalué, a sera faux, sinon && évaluera également (x == x).

& est un opérateur binaire, mais également un opérateur AND booléen qui ne court-circuite pas.

Vous pouvez les tester par quelque chose comme suit (voir combien de fois la méthode est appelée dans chaque cas):

public static boolean getFalse() {
    System.out.println("Method");
    return false;
}

public static void main(String[] args) {
    if(getFalse() && getFalse()) { }        
    System.out.println("=============================");        
    if(getFalse() & getFalse()) { }
}
4
Bhesh Gurung

Un court-circuit signifie que le deuxième opérateur ne sera pas vérifié si le premier opérateur décide du résultat final.

Par exemple. L'expression est: True || Faux

Dans le cas de ||, tout ce dont nous avons besoin est un des côtés pour être vrai. Donc, si le côté gauche est vrai, il ne sert à rien de vérifier le côté droit et par conséquent, cela ne sera pas vérifié du tout.

De même, False && True

Dans le cas de &&, nous avons besoin de des deux côtés pour être vrais. Donc, si le côté gauche est Faux, il est inutile de vérifier le côté droit, la réponse doit être Faux. Et par conséquent, cela ne sera pas vérifié du tout.

4
Bhushan

Java fournit deux opérateurs booléens intéressants, absents de la plupart des autres langages informatiques. Ces versions secondaires de AND et OR s'appellent opérateurs logiques de court-circuit. Comme vous pouvez le constater à partir du tableau précédent, l'opérateur OR renvoie true lorsque A est vrai, quel que soit B.

De même, l'opérateur AND génère false lorsque A est false, peu importe ce que B est. Si vous utilisez les formes || Et &&, Plutôt que les formes | Et & De ces opérateurs, Java ne dérangera pas d'évaluer l'opérande de droite seul. Ceci est très utile lorsque l'opérande de droite dépend du fait que celui de gauche soit vrai ou faux pour fonctionner correctement.

Par exemple, le fragment de code suivant montre comment vous pouvez tirer parti de l’évaluation logique par court-circuit pour vous assurer qu’une opération de division sera valide avant de l’évaluer:

if ( denom != 0 && num / denom >10)

Etant donné que la forme de court-circuit de AND (&&) Est utilisée, il n'y a aucun risque de provoquer la division par zéro d'une exception d'exécution. Si cette ligne de code était écrite avec la version unique & De AND, il faudrait évaluer les deux côtés, ce qui provoquerait une exception d'exécution lorsque denom serait égal à zéro.

Il est courant d’utiliser les formes de court-circuitement de AND et OR dans les cas impliquant la logique booléenne, les versions à un caractère étant réservées aux opérations au niveau du bit. Cependant, il existe des exceptions à cette règle. Par exemple, considérons l'énoncé suivant:

 if ( c==1 & e++ < 100 ) d = 100;

Ici, l’utilisation d’un seul & Garantit que l’opération d’incrémentation sera appliquée à e, que c soit égal à 1 ou non.

2
Dileep Kumar

Il y a quelques différences entre les & et && les opérateurs. Les mêmes différences s'appliquent à | et ||. La chose la plus importante à garder à l’esprit est que && est un opérateur logique qui s’applique uniquement aux opérandes booléens, tandis que & est un opérateur au niveau des bits qui s’applique aux types entiers ainsi qu’aux booléens.

Avec une opération logique, vous pouvez court-circuiter car dans certains cas (comme le premier opérande de && étant false, ou le premier opérande de || étant true), vous n'avez pas besoin d'évaluer le reste de l'expression. Ceci est très utile pour vérifier, par exemple, null avant d’accéder à un fichier ou à une méthode, et pour rechercher les zéros potentiels avant de les diviser. Pour une expression complexe, chaque partie de l'expression est évaluée de manière récursive de la même manière. Par exemple, dans le cas suivant:

(7 == 8) || ((1 == 3) && (4 == 4)) 

Seules les parties soulignées seront évaluées. Pour calculer le ||, vérifie d’abord si 7 == 8 est true. Si c'était le cas, le côté droit serait totalement ignoré. Le côté droit vérifie uniquement si 1 == 3 est false. Puisque c'est, 4 == 4 n'a pas besoin d'être vérifié et l'expression entière est évaluée à false. Si le côté gauche était true, par exemple. 7 == 7 au lieu de 7 == 8, tout le côté droit serait ignoré car tout le || expression serait true peu importe.

En mode binaire, vous devez évaluer tous les opérandes, car vous ne faites que combiner les bits. Les booléens sont en réalité un entier d'un bit dans Java (quel que soit le mode de fonctionnement des internes)], et ce n'est qu'un hasard si vous pouvez court-circuiter des opérateurs au niveau du bit dans ce cas particulier. La raison pour laquelle vous ne pouvez pas court-circuiter un entier général & ou | _ opération signifie que certains bits peuvent être activés et que certains peuvent être désactivés dans l’un ou l’autre opérande. Quelque chose comme 1 & 2 renvoie zéro, mais vous n’avez aucun moyen de le savoir sans évaluer les deux opérandes.

2
Mad Physicist

Logical OR: - renvoie true si au moins un des opérandes est évalué à true. Les deux opérandes sont évalués avant d'appliquer l'opérateur OR.

Short Circuit OR: - si l'opérande du côté gauche retourne vrai, il le retourne sans évaluer l'opérande du côté droit.

2
if(demon!=0&& num/demon>10)

Etant donné que la forme de court-circuit de AND (&&) est utilisée, il n’ya aucun risque de provoquer une exception d’exécution lorsque démon est à zéro.

Réf. Java 2 Cinquième édition de Herbert Schildt

1
Nitesh Verma