Die anderen Antworten haben den funktionalen Unterschied zwischen den Operatoren gut abgedeckt, aber die Antworten könnten für nahezu jede einzelne C-abgeleitete Sprache gelten, die heute existiert. Die Frage ist markiert mitJavaund so werde ich mich bemühen, spezifisch und technisch für die Java-Sprache zu antworten.
&
und |
können entweder ganzzahlige bitweise Operatoren oder boolesche logische Operatoren sein. Die Syntax für die bitweisen und logischen Operatoren ( §15.22 ) lautet:
AndExpression:
EqualityExpression
AndExpression & EqualityExpression
ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression ^ AndExpression
InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression | ExclusiveOrExpression
Die Syntax für EqualityExpression
ist in §15.21 definiert , was eine RelationalExpression
Definition in §15.20 erfordert , was wiederum erfordert ShiftExpression
und ReferenceType
in §15.19 bzw. §4.3 definiert ist. ShiftExpression
erfordert AdditiveExpression
in definierten §15.18 , die Definition der grundlegenden arithmetischen, unäre Operatoren etc. Drilldown weiter ReferenceType
bohrt nach unten in alle die verschiedenen Möglichkeiten , eine Art darzustellen. (Obwohl ReferenceType
die primitiven Typen nicht enthalten sind, ist letztendlich die Definition der primitiven Typen erforderlich, da sie der Dimensionstyp für ein Array sein können, bei dem es sich um a handelt ReferenceType
.)
Die bitweisen und logischen Operatoren haben die folgenden Eigenschaften:
- Diese Operatoren haben unterschiedliche Vorrang, wobei
&
sie den höchsten Vorrang haben und|
die niedrigste Priorität haben.
- Jeder dieser Operatoren ist syntaktisch linksassoziativ (jede Gruppe von links nach rechts).
- Jeder Operator ist kommutativ, wenn die Operandenausdrücke keine Nebenwirkungen haben.
- Jeder Operator ist assoziativ.
- Die bitweisen und logischen Operatoren können verwendet werden, um zwei Operanden vom numerischen Typ oder zwei Operanden vom Typ zu vergleichen
boolean
. Alle anderen Fälle führen zu einem Fehler bei der Kompilierung.
Die Unterscheidung, ob der Operator als bitweiser Operator oder als logischer Operator dient, hängt davon ab, ob die Operanden "in einen primitiven Integraltyp konvertierbar" sind ( §4.2 ) oder ob sie vom Typ sind boolean
oder Boolean
( §5.1.8 ).
Wenn die Operanden ganzzahlige Typen sind, wird für beide Operanden eine binäre numerische Heraufstufung ( §5.6.2 ) durchgeführt, wobei beide als long
s oder int
s für die Operation verbleiben . Der Typ der Operation ist der Typ der (heraufgestuften) Operanden. Zu diesem Zeitpunkt ist &
bitweises UND, ^
bitweises exklusives ODER und |
bitweises inklusive ODER. ( §15.22.1 )
Wenn die Operanden boolean
oder sind Boolean
, werden die Operanden bei Bedarf einer Unboxing-Konvertierung unterzogen ( §5.1.8 ), und der Typ der Operation ist boolean
. &
führt dazu, true
wenn beide Operanden sind true
, ^
führt dazu, true
wenn beide Operanden unterschiedlich sind, und |
führt dazu, true
wenn einer der Operanden ist true
. ( §15.22.2 )
Im Gegensatz dazu &&
ist der "Bedingte-Und-Operator" ( §15.23 ) und der "Bedingte-Und ||
-Operator" ( §15.24 ). Ihre Syntax ist definiert als:
ConditionalAndExpression:
InclusiveOrExpression
ConditionalAndExpression && InclusiveOrExpression
ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression || ConditionalAndExpression
&&
ist wie &
, außer dass es nur den rechten Operanden auswertet, wenn der linke Operand ist true
. ||
ist wie |
, außer dass es nur den rechten Operanden auswertet, wenn der linke Operand ist false
.
Bedingt-Und hat die folgenden Eigenschaften:
- Der Bedingungs- und Operator ist syntaktisch linksassoziativ (er gruppiert von links nach rechts).
- Der Bedingungs- und Operator ist sowohl in Bezug auf Nebenwirkungen als auch in Bezug auf den Ergebniswert vollständig assoziativ. Das heißt, für alle Ausdrücke
a
und b
, und die c
Bewertung des Ausdrucks ((a) && (b)) && (c)
führt zu demselben Ergebnis, wobei dieselben Nebenwirkungen in derselben Reihenfolge auftreten wie die Bewertung des Ausdrucks (a) && ((b) && (c))
.
- Jeder Operand des Bedingungs- und Operators muss vom Typ
boolean
oder sein Boolean
, sonst tritt ein Fehler bei der Kompilierung auf.
- Der Typ eines Bedingungs- und Ausdrucks ist immer
boolean
.
- Zur Laufzeit wird zuerst der linke Operandenausdruck ausgewertet. Wenn das Ergebnis einen Typ hat
Boolean
, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ).
- Wenn der resultierende Wert ist
false
, ist der Wert des Bedingungs- und Ausdrucksfalse
und der des rechten Operanden wird nicht ausgewertet.
- Wenn der Wert des linken Operanden ist
true
, wird der rechte Ausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean
, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ). Der resultierende Wert wird zum Wert der Bedingung und des Ausdrucks.
- Somit
&&
berechnet das gleiche Ergebnis wie &
auf boolean
Operanden. Es unterscheidet sich nur dadurch, dass der Ausdruck des rechten Operanden eher bedingt als immer ausgewertet wird.
Conditional-Or hat folgende Eigenschaften:
- Der Bedingungs- oder Operator ist syntaktisch linksassoziativ (er gruppiert von links nach rechts).
- Der Bedingungs- oder Operator ist in Bezug auf beide Nebenwirkungen und den Ergebniswert vollständig assoziativ. Das heißt, für alle Ausdrücke
a
, b
und c
, Auswertung des Ausdrucks ((a) || (b)) || (c)
erzeugt das gleiche Ergebnis, wobei die gleichen Nebenwirkungen in der gleichen Reihenfolge auftreten, wie Auswertung des Ausdrucks (a) || ((b) || (c))
.
- Jeder Operand des Bedingungs- oder Operators muss vom Typ
boolean
oder sein Boolean
, da sonst ein Fehler bei der Kompilierung auftritt.
- Der Typ eines Bedingungs- oder Ausdrucks ist immer
boolean
.
- Zur Laufzeit wird zuerst der linke Operandenausdruck ausgewertet. Wenn das Ergebnis einen Typ hat
Boolean
, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ).
- Wenn der resultierende Wert ist
true
, ist der Wert des Bedingungs- oder Ausdrucks true
und der Ausdruck des rechten Operanden wird nicht ausgewertet.
- Wenn der Wert des linken Operanden ist
false
, wird der rechte Ausdruck ausgewertet. Wenn das Ergebnis einen Typ hat Boolean
, wird es einer Unboxing-Konvertierung unterzogen ( §5.1.8 ). Der resultierende Wert wird zum Wert der Bedingung oder des Ausdrucks.
- Somit
||
berechnet das gleiche Ergebnis wie |
am boolean
oder Boolean
Operanden. Es unterscheidet sich nur dadurch, dass der Ausdruck des rechten Operanden eher bedingt als immer ausgewertet wird.
Kurz gesagt, wie @JohnMeagher hat wiederholt in den Kommentaren darauf hingewiesen, &
und |
ist in der Tat nicht-Kurzschließen Booleschen Operatoren in dem speziellen Fall der Operanden entweder boolean
oder Boolean
. Bei bewährten Verfahren (dh keine Nebenwirkungen) ist dies ein geringfügiger Unterschied. Wenn die Operanden jedoch nicht boolean
s oder Boolean
s sind, verhalten sich die Operatoren sehr unterschiedlich: Bitweise und logische Operationen lassen sich auf der hohen Ebene der Java-Programmierung einfach nicht gut vergleichen.