web-dev-qa-db-fra.com

Switch sans interruption

J'ai une déclaration de commutateur comme indiqué ci-dessous. Remarquez qu'il n'y a pas de pause. Findbugs signale une erreur sur la deuxième déclaration de cas uniquement. L'erreur est la suivante: instruction Switch trouvée où un cas passe au cas suivant.

switch(x) {

    case 0:
        // code

    case 1:
        // code

    case 2:
        // code
}
23
fastcodejava

Findbugs signale que le passage d'un case au suivant n'est généralement pas une bonne idée s'il y a du code dans le premier (bien qu'il puisse parfois être utilisé à bon escient). Ainsi, lorsqu'il voit le deuxième case et aucun break, il signale l'erreur.

Ainsi, par exemple:

switch (foo) {
    case 0:
        doSomething();
    case 1:
        doSomethingElse();
    default:
        doSomeOtherThing();
}

Il s'agit de Java parfaitement valide, mais il ne fait probablement pas ce que l'auteur a prévu: Si foo est 0, les trois fonctions doSomething, doSomethingElse et doSomeOtherThing run (dans cet ordre). Si foo est 1, seulement doSomethingElse et doSomeOtherThing s'exécutent. Si foo est une autre valeur, seule doSomeOtherThing s'exécute.

En revanche:

switch (foo) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

Ici, une seule des fonctions s'exécutera, selon la valeur de foo.

Comme c'est une erreur de codage courante d'oublier le break, des outils comme Findbugs le signalent pour vous.

Il existe un cas d'utilisation courant où vous avez plusieurs instructions case d'affilée avec aucun code intermédiaire:

switch (foo) {
    case 0:
    case 1:
        doSomething();
        break;
    case 2:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

Là, nous voulons appeler doSomething si foo est 0o1. La plupart des outils ne signalent pas cela comme une erreur de codage possible, car il n'y a pas de code dans le case 0 avant le case 1 et c'est un modèle assez courant.

72
T.J. Crowder

Je les ai écrites sous forme de commentaires mais ce n'est pas visible. Je les transforme en réponse. Il s'agit en fait d'une extension de réponse de T.J.Crowder .

Vous pouvez trouver la règle connexe qui fait que Findbugs signale une erreur ici .

Vous pouvez empêcher Findbugs de signaler ce type d'erreurs en créant un fichier xml avec le contenu suivant, par exemple filter.xml et exécuter l'outil avec -exclude filter.xml option. Voir filtres sur Findbugs .

<FindBugsFilter>
  <Match>
    <Bug category="PERFORMANCE" />
  </Match>
</FindBugsFilter>
4
melihcelik

Les raccourcis des commutateurs relèvent de la catégorie Findbugs du "code douteux". Je pense que cela ne signale que la première occurrence d'une erreur dans une instruction switch pour réduire le nombre de messages d'erreur.

3
Ted Hopp

Sans la pause, ils tomberont l'un dans l'autre, donc si x == 0 vous allez parcourir tout le code dans chaque bloc de déclaration de cas. Findbugs peut soit se tromper sur l'erreur, soit être une condition d'erreur sans interruption, c'est-à-dire quelque chose dans case 0 provoque quelque chose dans case 1 casser.

Sans le code exact et l'erreur, je ne peux pas vraiment aider davantage. L'absence de pauses est-elle délibérée?

2
Matt Fellows

Habituellement, les outils d'analyse de bogues n'aiment pas la chute du code, car dans la plupart des cas, l'utilisateur a juste oublié d'écrire la rupture.

Je ne sais pas s'il existe un moyen de désactiver spécifiquement l'avertissement avec FindBugs mais Checkstyle l'outil reconnaît les commentaires spéciaux tels que /* fallthrough * / pour supposer que l'utilisateur souhaite vraiment que le code suivant soit exécuté. Mettre ce type de commentaire améliore également la lisibilité. http://checkstyle.sourceforge.net/config_coding.html#FallThrough

La convention de code Java mentionne également l'utilisation de commentaires de substitution. http://www.Oracle.com/technetwork/Java/javase/documentation/codeconventions-142311.html

2
L2M

Si vos cas n'ont pas de pause, une fois qu'un cas est déclenché, le commutateur passera par tous les cas jusqu'à ce qu'il trouve une pause ou la fin des cas. Si vous avez un cas par défaut, il se déclenchera si la valeur de votre commutateur dans ce cas foo ne correspond à aucun autre cas.

0
Nisal Edu