Zunächst einige Hintergrundinformationen: Ich bin ein ausgebildeter IT-Lehrer und versuche, die Booleschen Operatoren von Java in meine Klasse der 10. Klasse einzuführen. Mein Lehrer-Mentor sah sich ein Arbeitsblatt an, das ich vorbereitet und kommentiert hatte, dass ich sie nur ein einziges & oder | verwenden lassen könnte die Operatoren zu bezeichnen, weil sie "dasselbe tun".
Mir ist der Unterschied zwischen & und && bewusst.
& ist ein bitweiser Operator, der für die Verwendung zwischen ganzen Zahlen vorgesehen ist, um "Bit-Twiddling" durchzuführen.
&& ist ein Bedingungsoperator, der für die Verwendung zwischen Booleschen Werten vorgesehen ist.
Um zu beweisen, dass diese Operatoren nicht immer "dasselbe tun", habe ich ein Beispiel gesucht, bei dem die Verwendung der bitweisen Werte zwischen Booleschen Werten zu einem Fehler führen würde. Ich habe dieses Beispiel gefunden
boolean bitwise;
boolean conditional;
int i=10, j=12;
bitwise = (i<j) | ((i=3) > 5); // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i<j) || (i=3) > 5 ; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
i=10;
bitwise = (i>j) & (i=3) > 5; // value of i after oper: 3
System.out.println(bitwise+ " "+ i);
i=10;
conditional = (i>j) && (i=3) > 5; // value of i after oper: 10
System.out.println(conditional+ " "+ i);
Dieses Beispiel zeigt, dass, wenn ein Wert in der zweiten Hälfte des Ausdrucks geändert werden muss, dies zu einem Unterschied zwischen den Ergebnissen führen würde, da bitweise ein eifriger Operator ist, während sich die Bedingung wie ein Kurzschluss verhält (die zweite nicht auswertet) half, wenn die erste Hälfte im Fall von && falsch ist, und true im Fall von ||).
Ich habe ein Problem mit diesem Beispiel. Warum möchten Sie einen Wert gleichzeitig mit einem Vergleich ändern? Es scheint keine robuste Art des Codierens zu sein. Ich war immer abgeneigt, in meinem Produktionscode mehrere Operationen in einer einzigen Zeile auszuführen. Es scheint etwas zu sein, was ein "Coding Cowboy" ohne Gewissen in Bezug auf die Wartbarkeit seines Codes tun würde. Ich weiß, dass Code in einigen Domänen so kompakt wie möglich sein muss, aber dies ist sicherlich eine schlechte Praxis im Allgemeinen.
Ich kann meine Entscheidung, die Verwendung von && und || zu fördern, erläutern über & und | denn dies ist eine anerkannte Kodierungskonvention in der Softwareentwicklung .
Aber könnte mir jemand bitte ein besseres, sogar reales Beispiel für die Verwendung eines bitweisen Operators in einem bedingten Ausdruck geben?
quelle
bitwise = !(true & true == false);
undcondition = !(true && true == false);
wird sowohl auf true zu bewerten, so dass in diesem Fall , dass sie austauschbar sind? Syntaktisch vielleicht, da der Code noch kompiliert. Ich würde zustimmen, dass sie semantisch für verschiedene Dinge verwendet werden, wie ich in Absatz 2 erwähnt habe. Das sagst du! und & "erscheinen fast nie in einer Bedingung für sich". Ich suche nach diesen "fast nie" Fällen und frage mich, ob sie legitim existieren.Die nicht-bitweisen Operatoren
&&
und||
sind Kurzschlussoperatoren. Mit anderen Worten,&&
wenn die LHS falsch ist, wird die RHS niemals ausgewertet. mit||
wenn die LHS wahr ist, dann wird die RHS nie ausgewertet. Auf der anderen Seite sind die bitweisen Operatoren&
und|
nicht kurzgeschlossen und werten immer sowohl die LHS als auch die RHS aus. Ansonsten sind sie in einerif
Aussage gleichwertig .Das einzige Mal, wenn ich einen Nutzen aus der Verwendung von Nicht-Kurzschluss-Operatoren ziehen kann, ist, dass die RHS eine Art von erwünschtem Nebeneffekt aufweist, den Sie auf jeden Fall haben möchten. Ich kann mir kein konkretes Beispiel vorstellen, an dem Sie dies wünschen würden, und ich glaube nicht, dass es eine gute Praxis ist, aber das ist der Unterschied.
quelle
Die allgemeine philosophische Antwort lautet, dass die Verwendung bitweiser Operatoren für boolesche Operatoren untypisch ist und das Lesen des Codes erschwert. In der Praxis (für Code, der sich in der Produktion befindet) ist besser lesbarer Code einfacher zu warten und daher wünschenswerter.
Informationen zur tatsächlichen Verwendung des Bedarfs an Kurzschlussbetreibern finden Sie in den folgenden Fällen:
Diese Art von Operationen wird häufig im Code der realen Welt angezeigt.
quelle
&
schwerer zu lesen ist als 2? Ich habe kein Beispiel, in dem die 2 Operatoren für Boolesche Operanden nicht auf die gleiche Weise funktionieren. Ich stimme Ihrer Meinung zu, dass Code lesbarer und leichter zu warten ist. Ich möchte sie ermutigen, schönen Code zu schreiben. Aber einen Beweis in meiner Werkzeugtasche zu haben, wäre überzeugender als „weil ich es gesagt habe“. Ich habe es als Standard bei diesem Link angegeben und muss mich möglicherweise darauf verlassen, wenn ich nicht das Beispiel bekomme, das ich suche. Wie ich @Steve Haigh fragte: Sollte Java dies als missbräuchliche Verwendung anzeigen?Sie verwenden bitweise Operatoren, wenn Sie Bitmasken-Enumerationen vergleichen. Sie haben beispielsweise eine Aufzählung von Zuständen und ein Objekt, das sich in mehr als einem dieser Zustände befinden kann. In diesem Fall müssen Sie Ihrem Objekt bitweise oder mehr als einen Status zuweisen.
zum Beispiel
state = CONNECTED | IN_PROGRESS
woCONNECTED could be 0x00000001
undIN_PROGRESS 0x00000010
Weitere Informationen finden Sie in der Dokumentation der Flaggenlisten.
quelle
ein einfacheres Beispiel für Unrecht:
Hier haben Sie zwei Bedingungen, beide sind nicht Null; aber das bitweise
&
ergibt null.quelle
(condA && condB)
fehler, da das && für 2int
s nicht funktioniert , nur 2 booleans.(condA & condB)
Solange es korrekt ist,int
ergibt es ein und in Java können wir nicht sagen,if(int)
dass es auch fehlerhaft ist. Du bist der erste, der versteht, wonach ich suche - genau das Beispiel für Unrecht .(Boolean(condA) && Boolean(condB))
Ich habe Java schon lange nicht mehr benutzt ... try (ich denke, esBoolean(x)
isttrue
für Ganzzahlen ungleich Null, oder?)((condA!=0) && (condB!=0))
?if (((condA!=0) && (condB!=0))) { System.out.println("correct"); } if (((condA!=0) & (condB!=0))) { System.out.println("never executed?"); }
führt beide print-Anweisungen aus.