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:
AndExpression:
EqualityExpression
AndExpression & EqualityExpression
ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression ^ AndExpression
InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression | ExclusiveOrExpression
La syntaxe de EqualityExpression
est définie au § 15.21 , qui nécessite d'être RelationalExpression
définie au § 15.20 , qui à son tour requiert ShiftExpression
et ReferenceType
définie au § 15.19 et au § 4.3 , respectivement. ShiftExpression
requiert AdditiveExpression
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'il ReferenceType
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 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 boolean
ou 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 long
s ou int
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
ou 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 true
si les deux opérandes le sont true
, ^
entraînera true
si les deux opérandes sont différents et |
entraînera true
si 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
, b
et 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
boolean
ou 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 false
et 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 boolean
opé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
, b
et 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
boolean
ouBoolean
, 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 true
et 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 boolean
ou Boolean
opé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 boolean
ou Boolean
. Avec les bonnes pratiques (ie: pas d'effets secondaires), c'est une différence mineure. Cependant, lorsque les opérandes ne sont pas boolean
s ou Boolean
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.