Also für binäre Operatoren auf booleans, Java hat &
, |
, ^
, &&
und ||
.
Fassen wir hier kurz zusammen, was sie tun:
- JLS 15.22.2 Boolesche logische Operatoren &, ^ und |
- JLS 15.23 Bedingter und Betreiber &&
- JLS 15.24 Bedingter oder Operator ||
Für
&
ist der Ergebniswert ,true
wenn beide Operanden - Werte sindtrue
; Andernfalls ist das Ergebnisfalse
.Für
|
ist der Ergebniswert ,false
wenn beide Operanden - Werte sindfalse
; Andernfalls ist das Ergebnistrue
.Für
^
ist der Ergebniswert ,true
wenn die Operandenwerte unterschiedlich sind; Andernfalls ist das Ergebnisfalse
.Der
&&
Operator ist wie&
, bewertet aber seinen rechten Operanden nur, wenn der Wert seines linken Operanden isttrue
.Der
||
Operator ist wie|
, bewertet seinen rechten Operanden jedoch nur, wenn der Wert seines linken Operanden gleich istfalse
.
Nun, unter allen 5, 3 davon haben Verbindung Zuordnung Versionen, nämlich |=
, &=
und ^=
. Meine Frage ist also offensichtlich: Warum bietet Java nicht &&=
und ||=
auch nicht? Ich finde, dass ich die mehr brauche als ich brauche &=
und |=
.
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.
Ab 15.26 Zuweisungsoperatoren :
Es gibt 12 Zuweisungsoperatoren. [...]
= *= /= %= += -= <<= >>= >>>= &= ^= |=
Es wurde die Bemerkung gemacht, dass wenn &&=
und ||=
implementiert würden, dies die einzigen Operatoren wären, die die rechte Seite nicht zuerst bewerten. Ich glaube, diese Vorstellung, dass ein zusammengesetzter Zuweisungsoperator zuerst die rechte Seite bewertet, ist ein Fehler.
Ab 15.26.2 Compound Assignment Operators :
Eine Verbindung Zuweisungsausdruck von der Form
E1 op= E2
entsprichtE1 = (T)((E1) op (E2))
, in demT
die Art derE1
Ausnahme , dassE1
nur einmal ausgewertet wird.
Als Beweis wirft das folgende Snippet ein NullPointerException
, kein ArrayIndexOutOfBoundsException
.
int[] a = null;
int[] b = {};
a[0] += b[-1];
quelle
Antworten:
Grund
Die Operatoren
&&=
und||=
sind auf Java nicht verfügbar, da diese Operatoren für die meisten Entwickler:Beispiel für
&&=
Wenn Java den
&&=
Operator erlaubt , dann dieser Code:wäre gleichbedeutend mit:
Dieser erste Code ist fehleranfällig, da viele Entwickler glauben, dass er
f2()
immer unabhängig vom zurückgegebenen Wert von f1 () aufgerufen wird. Es ist wie ,bool isOk = f1() && f2();
wof2()
nur , wenn sie aufgerufen wird ,f1()
kehrttrue
.Wenn der Entwickler
f2()
nur bei derf1()
Rückgabe aufgerufen werden möchte , isttrue
der zweite Code oben weniger fehleranfällig.Sonst reicht
&=
es aus, weil der Entwicklerf2()
immer angerufen werden möchte :Gleiches Beispiel aber für
&=
Darüber hinaus sollte die JVM diesen obigen Code wie folgt ausführen:
Vergleichen
&&
und&
ErgebnisseSind die Ergebnisse von Operatoren
&&
und&
dieselben, wenn sie auf boolesche Werte angewendet werden?Überprüfen wir dies mit dem folgenden Java-Code:
Ausgabe:
Daher können wir JA
&&
durch&
boolesche Werte ersetzen ;-)Also besser nutzen
&=
statt&&=
.Gleiches gilt für
||=
Gleiche Gründe wie für
&&=
: DerBediener
|=
ist weniger fehleranfällig als||=
.Wenn ein Entwickler
f2()
bei derf1()
Rücksendung nicht angerufen werden möchtetrue
, empfehle ich die folgenden Alternativen:oder:
quelle
&
und&&
geben Sie die gleichen Ergebnisse. Vielen Dank für Ihr Feedback. Gefällt dir meine Antwort? Prost.if (a) a = b
für Geschwindigkeit verwendena&=b;
ist schneller alsif(a) a=b;
bei der Verwendung von Werten, die in den CPU-Registern gespeichert sind. Befindetb
es sich jedoch im externen Speicher (nicht zwischengespeichert),if(a) a=b;
ist dies schneller. Ist es was du meinst? Bitte geben Sie mehr Beispielcode an ;-) Ich bin gespannt auf Ihre Meinung. Wir sehen uns. ProstisOK &&= f2();
möchte ich, dass es genauso kurzschließt wie es&&
tut.A = A op B
, sodass jeder genau weiß, was er tut, und sich selbst um die Auswirkungen kümmern kann. Wenn Ihre Gründe tatsächlich die Ursache für seine Abwesenheit wären, würde ich es als unerwünschte Bevormundung ansehen. Ich möchte mich jedoch bei Ihnen für das Hinzufügen der Zeile bedanken,bool isOk = f1() || f2() || f3() || f4();
da ich zu blind war, um mich selbst zu sehen.Wahrscheinlich weil so etwas
Es sieht so aus, als ob es zugewiesen
x
und bewertet werden solltesomeComplexExpression()
, aber die Tatsache, dass die Bewertung vom Wert vonx
abhängt, ist aus der Syntax nicht ersichtlich.Auch weil Javas Syntax auf C basiert und niemand die dringende Notwendigkeit sah, diese Operatoren hinzuzufügen. Mit einer if-Anweisung wären Sie wahrscheinlich sowieso besser dran.
quelle
x() && y()
aussieht, als ob es beide Seiten des Ausdrucks bewerten sollte. Offensichtlich akzeptieren die Leute, dass dies ein&&
Kurzschluss ist, so dass dies auch folgen sollte&&=
.a -= b;
würde ganz anders funktionieren alsa &&= b;
.Dies ist in Java so, weil es in C so ist.
Die Frage, warum dies in C so ist, ist, dass, als & und && unterschiedliche Operatoren wurden (einige Zeit vor Cs Abstieg von B), die & = Vielfalt der Operatoren einfach übersehen wurde.
Aber der zweite Teil meiner Antwort enthält keine Quellen, um sie zu sichern.
quelle
Vor allem, weil die Java-Syntax auf C (oder zumindest der C-Familie) basiert und in C alle diese Zuweisungsoperatoren zu arithmetischen oder bitweisen Assemblierungsanweisungen in einem einzelnen Register kompiliert werden. Die Zuweisungsoperator-Version vermeidet temporäre und hat möglicherweise effizienteren Code für frühe nicht optimierende Compiler erzeugt. Die Äquivalente (
&&=
und||=
) des logischen Operators (wie sie in C genannt werden) haben keine so offensichtliche Entsprechung zu einzelnen Montageanweisungen; Sie werden normalerweise zu einer Test- und Verzweigungssequenz von Anweisungen erweitert.Interessanterweise Sprachen wie Ruby tun haben || = und && =.
Bearbeiten: Die Terminologie unterscheidet sich zwischen Java und C.
quelle
&
,|
und^
;&&
und||
sind die bedingten Operatoren.bool
Typ. Das sind 20 Jahre in der Sprachgeschichte ohne Bool. Es gab keinen Grund dazu&&=
. bitweise Operationen waren genug.Eines der ursprünglichen Ziele von Java war es, "einfach, objektorientiert und vertraut" zu sein. In diesem Fall ist & = bekannt (C, C ++ haben es und in diesem Zusammenhang bekannt bedeutet, jemandem vertraut zu sein, der diese beiden kennt).
&& = wäre nicht vertraut und es wäre nicht einfach in dem Sinne, dass die Sprachdesigner nicht an jeden Operator denken wollten, den sie der Sprache hinzufügen könnten, so dass weniger zusätzliche Operatoren einfacher sind.
quelle
Für Boolesche Variablen && und || würde eine Kurzschlussauswertung verwenden, während & und | nicht, also würden Sie erwarten, dass && = und || = auch die Kurzschlussauswertung verwenden. Hierfür gibt es einen guten Anwendungsfall. Besonders wenn Sie über eine Schleife iterieren, möchten Sie schnell, effizient und knapp sein.
Anstatt zu schreiben
Ich möchte schreiben
und wissen, dass, sobald bVal wahr ist, fn () für den Rest der Iterationen nicht aufgerufen wird.
quelle
if (fn(item)) { bVal = true; break; }
.'
&
' und '&&
' sind nicht dasselbe wie '&&
' ist eine Abkürzungsoperation, die nicht ausgeführt wird, wenn der erste Operand falsch ist, während '&
' dies trotzdem tut (funktioniert sowohl mit number als auch mit 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.
Ich kann mir wirklich nicht vorstellen warum.
quelle
Es ist in Ruby erlaubt.
Wenn ich raten würde, würde ich sagen, dass es nicht häufig verwendet wird und daher nicht implementiert wurde. Eine andere Erklärung könnte sein, dass der Parser nur das Zeichen vor dem = betrachtet
quelle
Ich kann mir keinen besseren Grund vorstellen als "Es sieht unglaublich hässlich aus!"
quelle
&&=
hässlich halten&
überprüft beide Operanden, es ist ein bitweiser Operator. Java definiert mehrere bitweise Operatoren, die auf die Ganzzahltypen long, int, short, char und byte angewendet werden können.
&&
Beendet die Auswertung, wenn der erste Operand als falsch ausgewertet wird, da das Ergebnis falsch ist. Dies ist ein logischer Operator. Es kann auf Boolesche Werte angewendet werden.
Der Operator && ähnelt dem Operator &, kann jedoch Ihren Code etwas effizienter machen. Da beide vom Operator & verglichenen Ausdrücke wahr sein müssen, damit der gesamte Ausdruck wahr ist, gibt es keinen Grund, den zweiten Ausdruck auszuwerten, wenn der erste falsch zurückgibt. Der Operator & wertet immer beide Ausdrücke aus. Der Operator && wertet den zweiten Ausdruck nur aus, wenn der erste Ausdruck wahr ist.
Ein && = Zuweisungsoperator würde der Sprache nicht wirklich neue Funktionen hinzufügen. Die Arithmetik des bitweisen Operators ist viel aussagekräftiger. Sie können eine ganzzahlige bitweise Arithmetik ausführen, einschließlich der Booleschen Arithmetik. Die logischen Operatoren können lediglich Boolesche Arithmetik ausführen.
quelle
Brian Goetz (Java Language Architect bei Oracle) schrieb :
quelle
a & b und a && b sind nicht dasselbe.
a && b ist ein boolescher Ausdruck, der einen booleschen Wert zurückgibt, und a & b ist ein bitweiser Ausdruck, der ein int zurückgibt (wenn a und b Ints sind).
Was denkst du, sind sie gleich?
quelle