Java logischer Operator-Kurzschluss

Welcher Satz ist kurzgeschlossen, und was genau bedeutet es, dass der komplexe konditionale Ausdruck ein Kurzschluss ist?

public static void main(String[] args) { int x, y, z; x = 10; y = 20; z = 30; // TT // TF // FT // FF //SET A boolean a = (x < z) && (x == x); boolean b = (x < z) && (x == z); boolean c = (x == z) && (x  z); //SET B boolean aa = (x < z) & (x == x); boolean bb = (x < z) & (x == z); boolean cc = (x == z) & (x  z); } 

   

Die && und || Operatoren “Kurzschluss”, dh sie werten die rechte Seite nicht aus, wenn sie nicht notwendig ist.

Die & und | Operatoren werten, wenn sie als logische Operatoren verwendet werden, immer beide Seiten aus.

Es gibt nur einen Fall von Kurzschluss für jeden Betreiber, und sie sind:

  • false && ... – es ist nicht notwendig zu wissen, was die rechte Seite ist, das Ergebnis muss false
  • true || ... true || ... – es ist nicht notwendig zu wissen, was die rechte Seite ist, das Ergebnis muss true

Vergleichen wir das Verhalten in einem einfachen Beispiel:

 public boolean longerThan(String input, int length) { return input != null && input.length() > length; } public boolean longerThan(String input, int length) { return input != null & input.length() > length; } 

Die zweite Version verwendet den Nicht-Kurzschlußoperator & und wird eine NullPointerException casting, wenn die input null , aber die erste Version wird ohne eine Ausnahme false ;

SET A verwendet kurzschließende boolesche Operatoren.

Was “Kurzschließen” im Zusammenhang mit booleschen Operatoren bedeutet, ist, dass für eine Menge von booleschen Werten b1, b2, …, bn die Kurzschlußversionen die Auswertung beenden, sobald der erste dieser Booleans wahr ist (|| ) oder falsch (&&).

Beispielsweise:

 // 2 == 2 will never get evaluated because it is already clear from evaluating // 1 != 1 that the result will be false. (1 != 1) && (2 == 2) // 2 != 2 will never get evaluated because it is already clear from evaluating // 1 == 1 that the result will be true. (1 == 1) || (2 != 2) 

Kurzschlüsse bedeuten, dass der zweite Bediener nicht überprüft wird, wenn der erste Betreiber das Endergebnis entscheidet.

ZB Ausdruck ist: Wahr || Falsch

Im Falle von || brauchen wir nur eine Seite , um wahr zu sein. Wenn also die linke Seite wahr ist, hat es keinen Sinn, die rechte Seite zu überprüfen, und daher wird diese überhaupt nicht überprüft.

Ähnlich, Falsch && Wahr

Im Fall von && brauchen wir beide Seiten , um wahr zu sein. Wenn also die linke Seite falsch ist, hat es keinen Sinn, die rechte Seite zu überprüfen, die Antwort muss falsch sein. Und deshalb wird das überhaupt nicht überprüft werden.

 boolean a = (x < z) && (x == x); 

Diese Art wird kurzgeschlossen, dh wenn (x < z) zu falsch ausgewertet wird, dann wird letzteres nicht ausgewertet, a wird falsch sein, andernfalls wird && ebenfalls auswerten (x == x) .

& ist ein bitweiser Operator, aber auch ein boolescher UND-Operator, der nicht kurzschließt.

Sie können sie wie folgt testen (siehe wie oft die Methode in jedem Fall aufgerufen wird):

 public static boolean getFalse() { System.out.println("Method"); return false; } public static void main(String[] args) { if(getFalse() && getFalse()) { } System.out.println("============================="); if(getFalse() & getFalse()) { } } 

Kurz gesagt bedeutet Kurzschließen , dass man die Auswertung stoppt, wenn man weiß, dass sich die Antwort nicht mehr ändern kann. Wenn Sie zum Beispiel eine Kette von logischen AND evaluieren und Sie einen FALSE in der Mitte dieser Kette entdecken, wissen Sie, dass das Ergebnis falsch ist, egal was die Werte der restlichen Ausdrücke in der Kette sind . Das Gleiche gilt für eine Kette von OR : Sobald Sie einen TRUE , kennen Sie die Antwort sofort und können die restlichen Ausdrücke auslassen.

Sie geben Java an, dass Sie einen Kurzschluss haben möchten, indem Sie && anstelle von & und || anstelle von | . Der erste Satz in deinem Beitrag ist ein Kurzschluss.

Beachten Sie, dass dies mehr als ein Versuch ist, ein paar CPU-Zyklen zu speichern: in solchen Ausdrücken

 if (mystring != null && mystring.indexOf('+') > 0) { ... } 

Kurzschließen bedeutet einen Unterschied zwischen korrekter Operation und einem Absturz (in dem Fall, in dem mystring null ist).

Java bietet zwei interessante Boolesche Operatoren, die in den meisten anderen Computersprachen nicht vorkommen. Diese sekundären Versionen von AND und OR sind als logische Kurzschlussoperatoren bekannt. Wie Sie der vorhergehenden Tabelle entnehmen können, ergibt der Operator OR den Wert true, wenn A wahr ist, unabhängig davon, was B ist.

In ähnlicher Weise führt der UND-Operator zu false, wenn A falsch ist, egal, was B ist. Wenn Sie die || und && Formen, anstatt der | und & Formen dieser Operatoren, Java wird sich nicht die Mühe machen, den rechten Operanden allein zu bewerten. Dies ist sehr nützlich, wenn der rechte Operand davon abhängt, ob der linke Operand richtig oder falsch ist, um richtig zu funktionieren.

Das folgende Codefragment zeigt beispielsweise, wie Sie die logische Kurzschlussauswertung nutzen können, um sicherzustellen, dass eine Divisionsoperation vor der Auswertung gültig ist:

 if ( denom != 0 && num / denom >10) 

Da die Kurzform von AND ( && ) verwendet wird, besteht kein Risiko, dass eine Laufzeitausnahme durch Null dividiert wird. Wenn diese Codezeile mit der einzigen UND-Version von AND geschrieben würde, müssten beide Seiten ausgewertet werden, was zu einer Laufzeitausnahme führen würde, wenn der denom null ist.

Es ist üblich, die Kurzschlussformen von AND und OR in Fällen mit boolescher Logik zu verwenden, wobei die ein-Zeichen-Versionen ausschließlich für bitweise Operationen übrig bleiben. Es gibt jedoch Ausnahmen von dieser Regel. Betrachten Sie zum Beispiel die folgende Aussage:

  if ( c==1 & e++ < 100 ) d = 100; 

Hier wird mit einem einzigen & sichergestellt, dass die Inkrementoperation auf e angewendet wird, ob c gleich 1 ist oder nicht.

Logisches ODER: – gibt wahr zurück, wenn mindestens einer der Operanden als wahr ausgewertet wird. Beide Operanden werden vor Anwendung des OR-Operators ausgewertet.

Short Circuit ODER: – Wenn der linksseitige Operand true zurückgibt, wird true zurückgegeben, ohne den rechten Operanden auszuwerten.

 if(demon!=0&& num/demon>10) 

Da die Kurzform von AND (&&) verwendet wird, besteht keine Gefahr, dass eine Laufzeitausnahme verursacht wird, wenn der Dämon Null ist.

Ref. Java 2 Fünfte Ausgabe von Herbert Schildt

Es gibt ein paar Unterschiede zwischen den Operatoren & und && . Die gleichen Unterschiede gelten für | und || . Das Wichtigste, was zu beachten ist, ist, dass && ein logischer Operator ist, der nur für boolesche Operanden gilt, während & ist ein bitweiser Operator, der sowohl für Integer-Typen als auch für Booleans gilt.

Mit einer logischen Operation können Sie Kurzschlüsse durchführen, da Sie in bestimmten Fällen (wie der erste Operand von && false ist oder der erste Operand von || true ) den Rest des Ausdrucks nicht auswerten müssen. Dies ist sehr nützlich, um z. B. auf null prüfen, bevor auf ein Feld oder eine Methode zugegriffen wird, und nach möglichen Nullen zu suchen, bevor Sie durch sie dividieren. Für einen komplexen Ausdruck wird jeder Teil des Ausdrucks auf die gleiche Weise rekursiv ausgewertet. Zum Beispiel im folgenden Fall:

 (7 == 8) ||  ( (1 == 3) && (4 == 4))

Nur die hervorgehobenen Teile werden bewertet. Um das || zu berechnen Überprüfen Sie zuerst, ob 7 == 8 true . Wenn es so wäre, würde die rechte Seite komplett übersprungen werden. Auf der rechten Seite wird nur überprüft, ob 1 == 3 false . Da dies der Fall ist, muss 4 == 4 nicht überprüft werden, und der gesamte Ausdruck wird als false ausgewertet. Wenn die linke Seite true , zB 7 == 7 statt 7 == 8 , würde die gesamte rechte Seite übersprungen, weil das ganze || Ausdruck wäre unabhängig davon true .

Bei einer bitweisen Operation müssen Sie alle Operanden auswerten, da Sie nur die Bits kombinieren. Boolesche Werte sind tatsächlich eine Ein-Bit-Ganzzahl in Java (unabhängig davon, wie die Interna funktionieren), und es ist nur ein Zufall, dass Sie in diesem einen Spezialfall Kurzschlüsse für bitweise Operatoren machen können. Der Grund, dass Sie keine allgemeine Ganzzahl & oder | kurzschließen können Operation ist, dass einige Bits eingeschaltet sein können und einige in beiden Operanden ausgeschaltet sein können. Etwas wie 1 & 2 ergibt Null, aber Sie können das nicht wissen, ohne beide Operanden zu bewerten.