web-dev-qa-db-fra.com

Est-il mauvais de comparer explicitement avec les constantes booléennes, par ex. si (b == faux) en Java?

Est-ce mauvais d'écrire:

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

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

Est-il toujours préférable d'écrire plutôt:

if (!b) //...

while (!b) //...

Vraisemblablement, il n'y a pas de différence de performance (ou existe-t-il?), Mais comment jugez-vous le caractère explicite, la concision, la clarté, la lisibilité, etc. entre les deux?

Mettre à jour

Pour limiter la subjectivité, j'apprécierais également toutes les citations des directives de style de codage faisant autorité qui sont toujours préférables ou qui doivent être utilisées quand.


Remarque : le nom de variable b est simplement utilisé à titre d'exemple, ala foo et bar.

68
polygenelubricants

Ce n'est pas nécessairement mauvais, c'est tout simplement superflu. De plus, le nom de la variable pèse beaucoup. Je préférerais par exemple if (userIsAllowedToLogin) ci-dessus if (b) ou même pire if (flag).

En ce qui concerne les performances, le compilateur l’optimise de quelque manière que ce soit.

Update: en ce qui concerne les sources faisant autorité, je ne trouve pas explicitement quelque chose dans les conventions de codage Sun , mais au moins style de contrôle a un SimplifyBooleanExpression module qui avertirait à ce sujet.

61
BalusC

Vous ne devriez pas utiliser le premier style. J'ai vu des gens utiliser:

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

Personnellement, j'ai du mal à lire, mais c'est passable. Cependant, un gros problème que j'ai avec ce style est que cela mène aux exemples incroyablement contre-intuitifs que vous avez montrés:

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

Cela demande plus d’efforts de la part du lecteur pour déterminer l’intention de l’auteur. Personnellement, je trouve que l'inclusion d'une comparaison explicite à vrai ou à faux est redondante et donc plus difficile à lire, mais c'est moi.

47
Thomas

C'est une question de goût.

Personnellement, j’ai trouvé que if (!a) { est beaucoup moins lisible (EDIT: pour moi) que if (a == false) { et est donc plus sujet aux erreurs lors de la maintenance ultérieure du code, et j’ai converti pour utiliser le dernier formulaire.

Fondamentalement, je n'aime pas le choix des symboles pour les opérations logiques au lieu des mots (C ou Pascal), car mea = 10 and not b = 20 se lit plus facilement que a == 10 && !(b==20), mais c'est comme ça en Java.

Quiconque pose le "== faux" approche en faveur de "!" De toute évidence, il n'avait jamais trop regardé le code et raté le point d'exclamation. Oui, vous pouvez devenir aveugle au code.

32

La principale raison pour laquelle vous ne devriez pas utiliser le premier style est que ces deux éléments sont valides:

if (b = false) //...

while (b = true) //...

En d’autres termes, si vous omettez accidentellement un caractère, vous créez une affectation au lieu d’une comparaison. Une expression d'affectation correspond à la valeur attribuée. La première instruction ci-dessus affecte la valeur false à b et est évaluée à false. La seconde attribue true à b, ainsi elle est toujours évaluée à true, quoi que vous fassiez avec b dans la boucle.

24
Alan Moore

Je n'ai jamais vu le premier sauf en code écrit par des débutants; c'est toujours le dernier, et je ne pense pas que quiconque est vraiment dérouté par cela. D'autre part, je pense

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

contre

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

est beaucoup plus discutable, et dans ce cas, je préfère la deuxième

11
Michael Mrozek

IMHO, je pense que si vous faites juste les noms de variables bool précédés de "Is", ce sera plus évident et plus significatif, et ensuite, vous pouvez supprimer la comparaison explicite avec true ou false

Exemple:

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

etc

7
Mahesh Velaga

Je préfère le premier, parce que c'est plus clair. La machine peut lire aussi bien, mais j'essaie d'écrire du code pour que d'autres people lisent, pas seulement la machine.

5
Head Geek

Je préfère l'approche longue, mais je compare en utilisant == au lieu de != 99% du temps. 

Je sais que cette question concerne Java, mais je change souvent de langue. Par exemple, dans C#, comparer avec (pour isntance) == false peut aider à traiter avec des types bool nullables. J'ai donc eu cette habitude de comparer avec true ou false mais en utilisant l'opérateur ==

Je fais ces:

if(isSomething == false) ou if(isSomething == true)

mais je déteste ces:

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

pour des raisons évidentes de lisibilité! 

Tant que vous gardez votre code lisible, cela n'aura aucune importance.

3
Joel

Personnellement, je refactoriserais le code pour ne pas utiliser de test négatif. par exemple.

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

ou

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

IMHO, Dans 90% des cas, le code peut être remanié, le test négatif n'est donc pas requis.

2
Peter Lawrey

À mon avis, c'est tout simplement agaçant. Ce n'est pas quelque chose que je causerais un chahut.

1
ChaosPandion

C’est ma première réponse sur StackOverflow, alors soyez gentil ......... Récemment, lors du refactoring, j’ai remarqué que 2 blocs de code avaient presque exactement le même code, mais l’un utilisé avait 

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

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

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

et l'autre avait 

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

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

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

dans ce cas, il était donc logique de créer une méthode qui fonctionne pour les deux conditions comme celle-ci en utilisant boolean == condition pour inverser le sens

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

La recommandation normale est de ne jamais tester contre booléen. Certains soutiennent que la verbosité supplémentaire ajoute à la clarté. Le code ajouté peut aider certaines personnes, mais chaque lecteur devra lire plus de code.

Ce matin, j'ai perdu 1/2 heure pour trouver un bug. Le code était 

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

Si c'était codé avec la convention normale, j'aurais vu beaucoup plus vite que c'était faux:

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

Je dirais que c'est mauvais.

while (!b) {
    // do something 
}

lit beaucoup mieux que

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

Une des raisons pour lesquelles le premier (b == faux) est mal vu est que les débutants ne réalisent souvent pas que la seconde alternative (! B) est possible. Donc, utiliser la première forme peut indiquer une idée fausse avec des expressions booléennes et des variables booléennes. De cette façon, utiliser la seconde forme est devenu une sorte de sjiboleth: quand quelqu'un écrit ceci, il/elle comprend probablement ce qui se passe. 

Je pense que cela a rendu la différence plus importante qu’elle ne l’est réellement.

0
user3369540