it-swarm.com.de

Ist es schlecht, explizit mit booleschen Konstanten zu vergleichen, z. if (b == false) in Java?

Ist es schlecht zu schreiben:

if (b == false) //...

while (b != true) //...

Ist es immer besser, stattdessen zu schreiben:

if (!b) //...

while (!b) //...

Vermutlich gibt es keine Leistungsunterschiede (oder gibt es?), Aber wiegen Sie die Exklusivität, die Prägnanz, die Klarheit, die Lesbarkeit usw. zwischen den beiden?

Aktualisieren

Um die Subjektivität einzuschränken, würde ich mich auch über Zitate aus autoritativen Codierungsrichtlinien freuen, die immer vorzuziehen sind und welche wann verwendet werden sollen.


Note: Der Variablenname b wird nur als Beispiel verwendet, ala foo und bar.

68

Es ist nicht unbedingt schlecht, es ist nur überflüssig. Außerdem ist der tatsächliche Variablenname sehr gewichtet. Ich würde zum Beispiel if (userIsAllowedToLogin) vor if (b) oder noch schlimmer if (flag) vorziehen.

Der Compiler optimiert den Performance-Aspekt in jeder Hinsicht.

Update: Was die maßgebenden Quellen angeht, kann ich in den Sun-Codierungskonventionen nichts explizit finden, aber mindestens Checkstyle hat ein SimplifyBooleanExpression Modul, das darüber warnen würde.

61
BalusC

Sie sollten den ersten Stil nicht verwenden. Ich habe gesehen, wie Leute benutzt haben:

  • if ( b == true )
  • if ( b == false )

Ich persönlich finde es schwer zu lesen, aber es ist passabel. Ein großes Problem mit diesem Stil ist jedoch, dass er zu den unglaublich kontraintuitiven Beispielen führt, die Sie gezeigt haben:

  • if ( b != true )
  • if ( b != false )

Dies erfordert mehr Aufwand seitens des Lesers, um die Absicht des Autors zu bestimmen. Persönlich finde ich einen expliziten Vergleich mit true oder false überflüssig und damit schwerer zu lesen, aber das bin ich.

47
Thomas

Das ist stark Geschmackssache.

Ich persönlich habe festgestellt, dass if (!a) { viel weniger lesbar (EDIT: für mich) als if (a == false) { ist und daher fehleranfälliger ist, wenn der Code später verwaltet wird, und ich habe das letztere Formular verwendet.

Grundsätzlich mag ich die Wahl von Symbolen für logische Operationen anstelle von Wörtern (C versus Pascal) nicht, da mea = 10 and not b = 20 einfacher liest als a == 10 && !(b==20), aber so ist es in Java.

Jeder, der den "= false" -Ansatz zugunsten von "!" hatte offenbar nie zu lange auf Code gestarrt und dieses Ausrufezeichen verpasst. Ja, Sie können Code-Blind erhalten.

Der übergeordnete Grund, warum Sie den ersten Stil nicht verwenden sollten, ist, dass beide gültig sind:

if (b = false) //...

while (b = true) //...

Das heißt, wenn Sie versehentlich ein Zeichen weglassen, erstellen Sie eine Zuordnung anstelle eines Vergleichs. Ein Zuweisungsausdruck wertet den zugewiesenen Wert aus. Die erste Anweisung oben weist der Variablen false den Wert b zu und wertet false aus. Die zweite weist true der b zu, also wird sie immer zu true ausgewertet, unabhängig davon, was Sie mit b in der Schleife tun.

24
Alan Moore

Ich habe die erste nie gesehen, außer in Code, der von Anfängern geschrieben wurde. Es ist immer das Letzte, und ich glaube nicht, dass jemand wirklich verwirrt ist. Auf der anderen Seite denke ich

int x;
...
if(x) //...

vs

if(x != 0) //...

ist viel umstrittener, und in diesem Fall bevorzuge ich den zweiten

11
Michael Mrozek

IMHO, ich denke, wenn Sie die Bool-Variablennamen mit "Is" voranstellen, ist das selbstverständlich und aussagekräftiger. Dann können Sie den expliziten Vergleich mit true oder false entfernen

Beispiel:

isEdited  // use IsEdited in case of property names
isAuthorized // use IsAuthorized in case of property names

usw

7
Mahesh Velaga

Ich bevorzuge das erste, weil es klarer ist. Die Maschine kann beide gleich gut lesen, aber ich versuche, Code für andere Personen zu schreiben, nicht nur für die Maschine.

5
Head Geek

Ich bevorzuge den langen Ansatz, aber ich vergleiche == anstelle von != 99% der Zeit. 

Ich weiß, dass diese Frage Java betrifft, aber ich wechsle oft zwischen Sprachen. In C# kann zum Beispiel der Vergleich mit (für isntance) == false beim Umgang mit nullfähigen Bool-Typen helfen. Also habe ich dieses Verhalten mit true oder false verglichen, aber mit dem ==-Operator. 

Ich mache diese:

if(isSomething == false) oder if(isSomething == true)

aber ich hasse diese:

if(isSomething != false) oder if(isSomething != true)

aus offensichtlichen Gründen der Lesbarkeit! 

Solange Sie Ihren Code lesbar halten, ist es unwichtig.

3
Joel

Ich persönlich würde den Code umgestalten, so dass ich keinen negativen Test verwende. zum Beispiel.

if (b == false) {
   // false
} else {
   // true
}

oder

boolean b = false;
while(b == false) {
  if (condition)
      b = true;
}

IMHO, in 90% der Fälle kann der Code umgestaltet werden, so dass der negative Test nicht erforderlich ist.

2
Peter Lawrey

Meiner Meinung nach ist das einfach nervig. Nicht etwas, bei dem ich einen Krawall verursachen würde.

1
ChaosPandion

Dies ist meine erste Antwort auf StackOverflow, also seien Sie nett ....__ Vor kurzem habe ich beim Refactoring festgestellt, dass 2 Codeblöcke fast denselben Code hatten, der jedoch verwendet wurde 

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

und der andere hatte 

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (!vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

in diesem Fall war es also sinnvoll, eine Methode zu erstellen, die für beide Bedingungen geeignet war, indem boolean == condition verwendet wurde, um die Bedeutung umzukehren

private void appendCustomersToNotify(List<Alert> alerts
        List<Alert> customersToNotify, List<Long> vipList, boolean vip){

    for (Alert alert : alerts) {
        Long currentId = alertItem.getUserId();

        if (vip == vipList.contains(currentId)) {
            customersToNotify.add(alertItem);

            if (customersToNotify.size() == maxAlerts) {
                break;
            }
        }
    }
}
1
lifesoordinary

Die normale Richtlinie ist, niemals gegen Boolean zu testen. Einige argumentieren, dass die zusätzliche Ausführlichkeit zur Klarheit beiträgt. Der hinzugefügte Code kann manchen Leuten helfen, aber jeder Leser muss mehr Code lesen.

Heute morgen habe ich eine halbe Stunde verloren, um einen Fehler zu finden. Der Code war 

    if ( !strcmp(runway_in_use,"CLOSED") == IPAS_FALSE)
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");

Wenn es mit normaler Konvention codiert wäre, hätte ich viel schneller gesehen, dass es falsch war:

    if (strcmp(runway_in_use, "CLOSED"))
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");
1
BOC

Ich würde sagen, es ist schlecht.

while (!b) {
    // do something 
}

liest viel besser als

while (b != true) {
    // do something 
}
0
fastcodejava

Einer der Gründe, warum die erste (b == false) missbilligt wird, ist, dass Anfänger oft nicht erkennen, dass die zweite Alternative (! B) überhaupt möglich ist. Die Verwendung des ersten Formulars kann also auf ein Missverständnis mit booleschen Ausdrücken und booleschen Variablen hindeuten. Auf diese Weise wurde die Verwendung der zweiten Form zu einer Art Sjiboleth: Wenn jemand dies schreibt, versteht er/sie wahrscheinlich, was los ist. 

Ich glaube, dass dies dazu geführt hat, dass der Unterschied wichtiger ist als er wirklich ist.

0
user3369540