Warum hat Java keine zusammengesetzten Zuweisungsversionen der Bedingungs- und Bedingungsoperatoren? (&& =, || =)

63

So hat Java für binäre Operatoren auf booleschen Werten & , | , ^ , && und || .

Fassen wir zusammen, was sie hier kurz machen:

  

Für & ist der Ergebniswert true , wenn beide Operandenwerte true ; Andernfalls lautet das Ergebnis false .

     

Für | ist der Ergebniswert false , wenn beide Operandenwerte false ; Andernfalls lautet das Ergebnis true .

     

Für ^ ist der Ergebniswert true , wenn die Operandenwerte unterschiedlich sind; Andernfalls lautet das Ergebnis false .

     

Der Operator && ist wie & , aber wertet seinen rechten Operanden nur aus, wenn der Wert seines linken Operanden true ist.

     

Der || -Operator ist wie | , aber wertet seinen rechten Operanden nur aus, wenn der Wert seines linken Operanden false 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 entspricht E1 = (T)((E1) op (E2)) , wobei T dem Typ E1 entspricht, außer dass E1 nur einmal ausgewertet wird.

Als Beweis gibt das folgende Snippet eine NullPointerException , nicht eine ArrayIndexOutOfBoundsException .

%Vor%     
polygenelubricants 24.02.2010, 08:25
quelle

11 Antworten

14

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.

    
Josh Lee 24.02.2010 08:33
quelle
13

Grund

Die Operatoren &&= und ||= sind auf Java nicht verfügbar, da diese Operatoren für die meisten Entwickler sind:

  • fehleranfällig
  • nutzlos

Beispiel für &&=

Wenn Java &&= operator erlaubt hat, dann dieser Code:

%Vor%

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:

Gleiches Beispiel, aber für &=

%Vor%

Außerdem sollte die JVM diesen obigen Code wie folgt ausführen:

%Vor%

Vergleichen Sie && 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.

Gleiches für ||=

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:

%Vor%

oder:

%Vor%     
olibre 29.03.2012 15:30
quelle
7

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.

    
EFraim 01.10.2009 17:39
quelle
3

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>     

Yishai 01.10.2009 17:59
quelle
3

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

    
p00ya 24.02.2010 08:31
quelle
3

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.

    
zanfilip 21.02.2013 16:03
quelle
1

' & ' 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.

    
NawaMan 01.10.2009 17:50
quelle
0

Es ist in Ruby erlaubt.

Wenn ich raten würde, würde ich sagen, dass es nicht häufig verwendet wird, also wurde es nicht implementiert. Eine andere Erklärung könnte sein, dass der Parser nur das Zeichen vor dem =

betrachtet     
zzawaideh 01.10.2009 17:39
quelle
0

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?

    
Omry Yadan 01.10.2009 17:40
quelle
0

Ich kann mir keinen besseren Grund vorstellen als: "Es sieht unglaublich hässlich aus!"

    
Daniel Brückner 01.10.2009 17:40
quelle
0

& 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.

    
Elyasin 12.06.2015 13:20
quelle