Réponses:
Ce sont les opérateurs ET et OU au niveau du bit.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Merci à Carlos d'avoir indiqué la section appropriée dans la spécification du langage Java ( 15.22.1 , 15.22.2 ) concernant les différents comportements de l'opérateur en fonction de ses entrées.
En effet, lorsque les deux entrées sont booléennes, les opérateurs sont considérés comme les opérateurs logiques booléens et se comportent de la même manière que les opérateurs Conditional-And ( &&
) et Conditional-Or ( ||
) à l'exception du fait qu'ils ne court-circuitent pas alors que ce qui suit est sûr :
if((a != null) && (a.something == 3)){
}
Ce n'est pas:
if((a != null) & (a.something == 3)){
}
«Court-circuit» signifie que l'opérateur n'examine pas nécessairement toutes les conditions. Dans les exemples ci-dessus, &&
examinera la deuxième condition uniquement lorsque ce a
n'est pas le null
cas (sinon la déclaration entière retournera false, et il serait de toute façon inutile d'examiner les conditions suivantes), donc la déclaration de a.something
ne lèvera pas d'exception, ou est considérée comme "sûre . "
L' &
opérateur examine toujours chaque condition de la clause, donc dans les exemples ci-dessus, a.something
peut être évalué quand a
est en fait une null
valeur, ce qui déclenche une exception.
Je pense que vous parlez de la signification logique des deux opérateurs, ici vous avez un tableau-CV:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
L'évaluation de court-circuit, l'évaluation minimale ou l'évaluation de McCarthy (d'après John McCarthy) est la sémantique de certains opérateurs booléens dans certains langages de programmation dans lesquels le deuxième argument est exécuté ou évalué uniquement si le premier argument ne suffit pas à déterminer la valeur du expression: lorsque le premier argument de la fonction AND prend la valeur false, la valeur globale doit être false; et lorsque le premier argument de la fonction OR est évalué à vrai, la valeur globale doit être vraie.
Not Safe signifie que l'opérateur examine toujours chaque condition de la clause, donc dans les exemples ci-dessus, 1 / x peut être évalué lorsque x est, en fait, une valeur 0, ce qui déclenche une exception.
Je sais qu'il y a beaucoup de réponses ici, mais elles semblent toutes un peu déroutantes. Donc, après avoir fait quelques recherches dans le guide d'étude Java oracle, j'ai proposé trois scénarios différents pour savoir quand utiliser && ou &. Les trois scénarios sont logiques et , au niveau du bit et booléen ET .
ET logique: ET
logique (aka ET conditionnel) utilise l' opérateur && . C'est un sens court-circuité: si l'opérande gauche est faux, l'opérande droit ne sera pas évalué.
Exemple:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
Dans l'exemple ci-dessus, la valeur imprimée sur la console de x sera 0, car le premier opérande de l'instruction if est faux, donc java n'a pas besoin de calculer (1 == ++ x) donc x ne sera pas calculé.
ET au niveau du bit: ET au niveau du bit utilise l' opérateur & . Il est utilisé pour effectuer une opération au niveau du bit sur la valeur. Il est beaucoup plus facile de voir ce qui se passe en regardant l'opération sur les nombres binaires ex:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Comme vous pouvez le voir dans l'exemple, lorsque les représentations binaires des nombres 5 et 12 sont alignées, alors un ET au niveau du bit préformé ne produira qu'un nombre binaire où le même chiffre dans les deux nombres aura un 1. Par conséquent 0101 & 1100 == 0100. Qui en décimal est 5 & 12 == 4.
Booléen AND: L'opérateur booléen AND se comporte désormais de manière similaire et différente à la fois au ET au niveau du bit et au ET logique. J'aime le penser comme préformant un ET au niveau du bit entre deux valeurs booléennes (ou bits), donc il utilise l' opérateur & . Les valeurs booléennes peuvent également être le résultat d'une expression logique.
Il renvoie une valeur vraie ou fausse, un peu comme le ET logique, mais contrairement au ET logique, il n'est pas court-circuité. La raison en est que pour préformer ce ET au niveau du bit, il doit connaître la valeur des opérandes gauche et droit. Voici un ex:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Maintenant, lorsque cette instruction if est exécutée, l'expression (1 == ++ x) sera exécutée, même si l'opérande de gauche est faux. Par conséquent, la valeur imprimée pour x sera 1 car elle a été incrémentée.
Ceci s'applique également aux OR logique (||), OR au niveau du bit (|) et OR booléen (|) J'espère que cela dissipe une certaine confusion.
to preform that bitwise AND, it must know the value of both left and right operands
Cela ne me semble pas juste. Pour effectuer un, BITWISE AND
vous n'avez pas besoin de connaître l'opérande de droite pour pouvoir déterminer le résultat si l'opérande de gauche est FALSE
. Ce que vous expliquez est correct, mais le raisonnement que vous énoncez ne me paraît pas le cas, du moins à moi.
Les opérateurs && et || sont en court-circuit, ce qui signifie qu'ils n'évalueront pas leur expression de droite si la valeur de l'expression de gauche est suffisante pour déterminer le résultat.
& et | fournissent le même résultat que les && et || les opérateurs. La différence est qu'ils évaluent toujours les deux côtés de l'expression où comme && et || arrêtez d'évaluer si la première condition est suffisante pour déterminer le résultat.
&&
il évalue les deux résultats tandis qu'il ||
ne renvoie que si la première condition est vraie.
( 2 & 4 )
évalue à false
, alors que ( 2 && 4 )
évalue à true
. En quoi exactement le même résultat?
2 & 4
donne un entier et non un booléen (zéro dans ce cas). 2 && 4
ne compilera pas, && n'acceptera que les booléens. Java ne permet pas de mélanger des booléens et des entiers: zéro n'est pas false
, false
n'est pas zéro ...
&&
il n'évalue le deuxième opérande que si le premier opérande l'est true
.
En Java, les opérateurs uniques &, |, ^,! dépendent des opérandes. Si les deux opérandes sont des entiers, une opération au niveau du bit est effectuée. Si les deux sont des booléens, une opération "logique" est effectuée.
Si les deux opérandes ne correspondent pas, une erreur de compilation est générée.
Les opérateurs doubles &&, || se comportent de la même manière que leurs homologues simples, mais les deux opérandes doivent être des expressions conditionnelles, par exemple:
if ((a <0) && (b <0)) {...} ou similaire, if ((a <0) || (b <0)) {...}
source: programmation java lang 4th ed
&
et |
sont des opérateurs binaires sur des types intégraux (par exemple int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
et ne ||
fonctionnent que sur des booléens (et court-circuit, comme d'autres réponses l'ont déjà dit).
&
et |
sont également des opérateurs booléens sur les types booléens.
Peut-être qu'il peut être utile de savoir que les opérateurs binaires AND et binaires OR sont toujours évalués avant AND conditionnel et OR conditionnel utilisé dans la même expression.
if ( (1>2) && (2>1) | true) // false!
&&; || sont des opérateurs logiques ... court-circuit
&; | sont des opérateurs logiques booléens ... Non court-circuit
Passer aux différences d'exécution sur les expressions. Les opérateurs au niveau du bit évaluent les deux côtés indépendamment du résultat du côté gauche. Mais dans le cas de l'évaluation d'expressions avec des opérateurs logiques, l'évaluation de l'expression de droite dépend de la condition de gauche.
Par exemple:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Cela affichera i = 26; j = 25, comme la première condition est fausse, la condition de la main droite est contournée car le résultat est de toute façon faux quelle que soit la condition du côté droit. (court-circuit)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Mais, cela affichera i = 26; j = 26,
Si une expression impliquant le booléen & opérateur est évaluée, les deux opérandes sont évalués. Ensuite, l'opérateur & est appliqué à l'opérande.
Lorsqu'une expression impliquant le && opérateur est évaluée, le premier opérande est évalué. Si le premier opérande est évalué à faux, l'évaluation du deuxième opérande est ignorée.
Si le premier opérande renvoie la valeur true, le deuxième opérande est évalué. Si le second opérande renvoie la valeur true, l'opérateur && est alors appliqué aux premier et second opérandes.
Similaire pour | et ||.
Bien que la différence fondamentale soit qu'elle &
est utilisée pour les opérations au niveau du bit principalement sur long
, int
ou byte
lorsqu'elle peut être utilisée pour une sorte de masque, les résultats peuvent différer même si vous l'utilisez au lieu de&&
.
La différence est plus notable dans certains scénarios:
Le premier point est assez simple, il ne provoque aucun bogue, mais cela prend plus de temps. Si vous avez plusieurs vérifications différentes dans une instruction conditionnelle, placez celles qui sont moins chères ou plus susceptibles d'échouer à gauche.
Pour le deuxième point, voir cet exemple:
if ((a != null) & (a.isEmpty()))
Cela échoue null
, car l'évaluation de la deuxième expression produit un NullPointerException
. L'opérateur logique &&
est paresseux, si l'opérande gauche est faux, le résultat est faux quel que soit l'opérande droit.
Exemple pour le troisième point - disons que nous avons une application qui utilise DB sans aucun déclencheur ni cascades. Avant de supprimer un objet Building, nous devons remplacer le bâtiment d'un objet Department par un autre. Supposons également que l'état de l'opération soit renvoyé sous forme de valeur booléenne (vrai = succès). Ensuite:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Cela évalue les deux expressions et effectue ainsi la suppression du bâtiment même si la mise à jour du service a échoué pour une raison quelconque. Avec&&
, cela fonctionne comme prévu et s'arrête après la première panne.
Quant à a || b
, il équivaut à !(!a && !b)
, il s'arrête si a
c'est vrai, aucune autre explication n'est nécessaire.