it-swarm-pt.tech

Mudar sem interrupção

Eu tenho alguma instrução switch, como mostrado abaixo. Observe que não há interrupção. Findbugs está relatando erro apenas na segunda declaração de caso. O erro é: A instrução Switch foi encontrada onde um caso cai para o próximo caso.

switch(x) {

    case 0:
        // code

    case 1:
        // code

    case 2:
        // code
}
23
fastcodejava

Findbugs está sinalizando que passar de um case para o próximo geralmente não é uma boa idéia se houver algum código no primeiro (embora às vezes possa ser usado com bom efeito). Portanto, quando vê o segundo case e não break, ele relata o erro.

Então, por exemplo:

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

Isso é Java perfeitamente válido, mas provavelmente não faz o que o autor pretendia: Se foo for 0, todas as três das funções doSomething, doSomethingElse e doSomeOtherThing executam (em essa ordem). Se foo for 1, apenas doSomethingElse e doSomeOtherThing são executados. Se foo for qualquer outro valor, apenas doSomeOtherThing será executado.

Em contraste:

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

Aqui, apenas uma das funções será executada, dependendo do valor de foo.

Como é um erro de codificação comum esquecer o break, ferramentas como o Findbugs o sinalizam para você.

Há um caso de uso comum em que você tem várias instruções case seguidas com no código interveniente:

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

Lá, queremos chamar doSomething se foo for 0o1. A maioria das ferramentas não sinaliza isso como um possível erro de codificação, porque não há código no case 0 antes do case 1 e esse é um padrão bastante comum.

72
T.J. Crowder

Eu os escrevi como comentários, mas não é visível. Estou transformando-os em uma resposta. Esta é realmente uma extensão para resposta de T.J. Crowder .

Você pode encontrar a regra relacionada que faz com que o Findbugs relate um erro aqui .

Você pode impedir que o Findbugs relate esse tipo de erro criando um arquivo xml com o seguinte conteúdo, digamos filter.xml e executando a ferramenta com -exclude filter.xml opção. Veja filtros no Findbugs .

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

As trocas de interruptores se enquadram na categoria Findbugs de "código desonesto". Eu acho que apenas sinaliza a primeira ocorrência de uma falha em uma instrução switch para reduzir o número de mensagens de erro.

3
Ted Hopp

Sem o intervalo, eles cairão um no outro, se x == 0 você passará por todo o código em cada bloco de instrução de caso. O Findbugs pode estar errado sobre o erro ou pode ser uma condição de erro sem a interrupção, ou seja, algo em case 0 causa algo em case 1 quebrar.

Sem o código e o erro exatos, não posso ajudar mais. A falta de pausas é deliberada?

2
Matt Fellows

Geralmente, as ferramentas de análise de bugs não gostam da inovação no código, porque na maioria dos casos, o usuário esqueceu de escrever a interrupção.

Não sei se existe uma maneira de desativar especificamente o aviso com FindBugs , mas a ferramenta Checkstyle reconhece comentários especiais como = /* fallthrough * / para assumir que o usuário realmente deseja que o seguinte código seja executado. Colocar esse tipo de comentário também melhora a legibilidade. http://checkstyle.sourceforge.net/config_coding.html#FallThrough

A convenção de código Java também menciona o uso de comentários de avanço. http://www.Oracle.com/technetwork/Java/javase/documentation/codeconventions-142311.html

2
L2M

Se seus casos não tiverem interrupção, uma vez que o caso for acionado, o comutador passará por todos os casos até encontrar uma interrupção ou final dos casos. Se você tiver um caso padrão, ele será acionado se o valor do seu comutador neste caso foo não corresponder a nenhum outro caso.

0
Nisal Edu