So hat Java für binäre Operatoren auf booleschen Werten &
, |
, ^
, &&
und ||
.
Fassen wir zusammen, was sie hier kurz machen:
Für
&
ist der Ergebniswerttrue
, wenn beide Operandenwertetrue
; Andernfalls lautet das Ergebnisfalse
.Für
|
ist der Ergebniswertfalse
, wenn beide Operandenwertefalse
; Andernfalls lautet das Ergebnistrue
.Für
^
ist der Ergebniswerttrue
, wenn die Operandenwerte unterschiedlich sind; Andernfalls lautet das Ergebnisfalse
.Der Operator
&&
ist wie&
, aber wertet seinen rechten Operanden nur aus, wenn der Wert seines linken Operandentrue
ist.Der
||
-Operator ist wie|
, aber wertet seinen rechten Operanden nur aus, wenn der Wert seines linken Operandenfalse
ist.
Nun haben von allen 5, 3 von denen Verbundversionen, nämlich |=
, &=
und ^=
. Meine Frage ist also offensichtlich: Warum stellt Java nicht auch &&=
und ||=
zur Verfügung? Ich finde, dass ich diese mehr brauche als ich &=
und |=
brauche.
Und ich denke nicht, dass "weil es zu lang ist" eine gute Antwort ist, weil Java >>>=
hat. Es muss einen besseren Grund für diese Unterlassung geben.
Von 15.26 Zuweisungsoperatoren :
Es gibt 12 Zuweisungsoperatoren; [...]
= *= /= %= += -= <<= >>= >>>= &= ^= |=
Es wurde ein Kommentar gemacht, dass, wenn &&=
und ||=
implementiert wären, dies die einzigen Operatoren wären, die die rechte Seite nicht zuerst bewerten würden. Ich glaube, dass diese Vorstellung, dass ein zusammengesetzter Zuweisungsoperator die rechte Seite zuerst bewertet, ein Fehler ist.
Von 15.26.2 Zusammengesetzte Zuweisungsoperatoren :
Ein zusammengesetzter Zuweisungsausdruck der Form
E1 op= E2
entsprichtE1 = (T)((E1) op (E2))
, wobeiT
dem TypE1
entspricht, außer dassE1
nur einmal ausgewertet wird.
Als Beweis gibt das folgende Snippet eine NullPointerException
, nicht eine ArrayIndexOutOfBoundsException
.
Wahrscheinlich weil sowas wie
%Vor% sieht so aus, als müsste es x
zuweisen und someComplexExpression()
auswerten, aber die Tatsache, dass die Bewertung vom Wert von x
abhängt, ist aus der Syntax nicht ersichtlich.
Auch weil die Syntax von Java auf C basiert, und niemand sah eine dringende Notwendigkeit, diese Operatoren hinzuzufügen. Sie wären wahrscheinlich mit einer if-Anweisung besser dran.
Die Operatoren &&=
und ||=
sind auf Java nicht verfügbar, da diese Operatoren für die meisten Entwickler sind:
&&=
Wenn Java &&=
operator erlaubt hat, dann dieser Code:
wäre äquivalent zu:
%Vor% Dieser erste Code ist fehleranfällig , weil viele Entwickler denken würden, dass f2()
immer unabhängig vom Rückgabewert von f1 () aufgerufen wird. Es ist wie bool isOk = f1() && f2();
, wobei f2()
nur aufgerufen wird, wenn f1()
true
zurückgibt.
Wenn der Entwickler f2()
nur dann aufrufen möchte, wenn f1()
true
zurückgibt, ist der zweite obige Code weniger fehleranfällig.
Else &=
ist ausreichend, weil der Entwickler f2()
immer aufrufen will:
&=
Außerdem sollte die JVM diesen obigen Code wie folgt ausführen:
%Vor%&&
und &
Ergebnisse Sind die Ergebnisse der Operatoren &&
und &
gleich, wenn sie auf boolesche Werte angewendet werden?
Sehen wir uns den folgenden Java-Code an:
%Vor%Ausgabe:
%Vor% Daher YES können wir &&
durch &
für boolesche Werte ersetzen ;-)
Also besser &=
anstelle von &&=
verwenden.
||=
Gleiche Gründe wie für &&=
:
Der Operator |=
ist weniger fehleranfällig als ||=
.
Wenn ein Entwickler möchte, dass f2()
nicht aufgerufen wird, wenn f1()
true
zurückgibt, dann rate ich die folgenden Alternativen:
oder:
%Vor%Es ist so in Java, weil es so in C ist.
Nun ist die Frage, warum es so in C ist, weil wenn & amp; und & amp; & amp; zu verschiedenen Operatoren (irgendwann vor Cs Abstieg von B), wurde die & amp; = Vielfalt der Operatoren einfach übersehen.
Aber der zweite Teil meiner Antwort hat keine Quellen, um das zu belegen.
Eines der ursprünglichen Ziele war "einfach, objektorientiert und Familiär." In diesem Fall ist & amp; = bekannt (C, C ++ hat es und vertraut in diesem Zusammenhang vertraut für jemanden, der diese beiden kennt).
& amp; & amp; = wäre nicht vertraut, und es wäre nicht einfach in dem Sinne, dass die Sprachdesigner nicht an jeden Operator denken würden, den sie der Sprache hinzufügen könnten, so dass weniger zusätzliche Operatoren einfacher sind / p>
Dies liegt hauptsächlich daran, dass die Java-Syntax auf C (oder zumindest der C-Familie) basiert, und in C werden alle diese Zuweisungsoperatoren zu arithmetischen oder bitweisen Assembleranweisungen in einem einzigen Register kompiliert. Die Zuweisungsoperatorversion vermeidet Provisorien und hat möglicherweise effizienteren Code für frühe nicht optimierende Compiler erzeugt. Die logischen Operatoräquivalente ( &&=
und ||=
) haben keine so offensichtliche Entsprechung zu einzelnen Assembleranweisungen; sie erweitern sich normalerweise zu einer Test- und Verzweigungssequenz von Anweisungen.
Interessanterweise haben Sprachen wie Ruby do || = und & amp; & amp;;.
Bearbeiten: Die Terminologie unterscheidet zwischen Java und C
Für boolesche Variablen, & amp; & amp; und || würde die Kurzschlussauswertung verwenden, während & amp; und | nicht, also würden Sie erwarten, dass & amp; & amp; = und || = auch eine Kurzschlussauswertung verwenden. Dafür gibt es einen guten Anwendungsfall. Besonders wenn Sie über eine Schleife iterieren, möchten Sie schnell, effizient und kurz sein.
Anstatt zu schreiben
%Vor%Ich möchte schreiben
%Vor%und wissen, dass, sobald bVal wahr ist, fn () für den Rest der Iterationen nicht aufgerufen wird.
' &
' und ' &&
' sind nicht dasselbe wie ' &&
' ist eine Abkürzung, die nicht funktioniert, wenn der erste Operand falsch ist, während ' &
' es trotzdem tut ( arbeitet mit boolean und boolean).
Ich stimme zu, dass es sinnvoller ist zu existieren, aber es ist nicht so schlimm, wenn es nicht da ist. Ich denke, es war nicht da, weil C es nicht hat.
Kann wirklich nicht an warum denken.
a & amp; b und a & amp; & amp; b sind nicht dasselbe.
a & amp; & amp; b ist ein boolescher Ausdruck, der einen booleschen Wert zurückgibt, und ein & amp; b ist ein bitweiser Ausdruck, der ein int zurückgibt (wenn a und b Inte sind).
Was denkst du, sind sie gleich?
Ich kann mir keinen besseren Grund vorstellen als: "Es sieht unglaublich hässlich aus!"
& amp;
prüft beide Operanden, es ist ein bitweiser Operator. Java definiert mehrere bitweise Operatoren, die auf die Integer-Typen long, int, short, char und byte angewendet werden können.
& amp; & amp;
beendet die Auswertung, wenn der erste Operand false ergibt, da das Ergebnis false ist, es handelt sich um einen logischen Operator. Es kann auf boolesche Werte angewendet werden.
Die & amp; & amp; Betreiber ist ähnlich wie die & amp; Operator, kann aber Ihren Code ein wenig effizienter machen. Weil beide Ausdrücke von & amp; Der Operator muss für den gesamten Ausdruck wahr sein, damit er wahr ist. Es gibt keinen Grund, den zweiten Ausdruck zu bewerten, wenn der erste Ausdruck false zurückgibt. Die & amp; Der Operator wertet immer beide Ausdrücke aus. Die & amp; & amp; Der Operator wertet den zweiten Ausdruck nur aus, wenn der erste Ausdruck wahr ist.
Wenn Sie einen & amp; & amp; = Zuweisungsoperator haben, würden Sie der Sprache nicht wirklich neue Funktionen hinzufügen. Die Arithmetik des bitweisen Operators ist viel expressiver, Sie können Ganzzahl-Bit-Arithmetik durchführen, die Boole'sche Arithmetik einschließt. Die logischen Operatoren können lediglich boolesche Arithmetik ausführen.