7
respostas

Switch sem o comando break

Boa Tarde,

Durante meus estudos em Java, me deparei com a seguinte situação. Porque quando vc utiliza o switch/case sem o break, ele executa todos os cases após a condição ser verdadeira mesmo a condição destes outros case nao sendo verdadeira? Como funciona essa palavra reservada internamente?

Segue exemplo do código:

int mes = 8;
switch (mes) {
    case 1:
    case 2:
    case 8:Sysout("oi")
    case 9:Sysout("oi")
    case 10:Sysout("oi")
}

Output: oi oi oi

Poderiam me explicar, porque isso acontece?

Abraços

7 respostas

Olá, Thiago.

O comportamento do Switch (bem basicamente) é: Executar o código a partir do case de sucesso, até encontrar um break.

Isso não é só do Java. Qualquer linguagem de programação é assim.

Boa tarde Thiago,

Ao invés de explicar, deixarei o link e a ótima explicação dada pelo ViniGodoy no GUJ:

http://www.guj.com.br/t/switch-case-qual-e-a-sua-funcao/78862/18

"O switch não testa intervalos. O que esse código fez foi dividir grade por 10, numa divisão de inteiros, para que notas como 80,81,82,83,84,85,87,88 e 89, virassem simplesmente 8. Com esse artifício, o switch então pode só testar a parte do número na casa das dezenas.

O switch é muito parecido com um if. Um switch assim:

switch (opcao) {
   case 1:
       fazAlgo();
       break;
   case 2:
   case 3:
       fazOutraCoisa();
       break;
    default:
       fazUmaTerceiraCoisa();
       break;
}

É equivalente ao if:

if (opcao == 1) {
   fazAlgo();
} else if (opcao == 2 || opcao == 3) {
   fazOutraCoisa();
} else {
   fazUmaTerceiraCoisa();
}

Note que sem o break, o switch faz o que chamamos de "fall through". Ou seja, ele entra na condição que estiver abaixo dele. O exemplo acima é um caso onde usamos fallthrough da maneira correta. Abaixo, mostro um exemplo onde um erro de programação pode gerar um comportamento inesperado:

switch (opcao) {
   case 1:
       fazAlgo(); //Ops, esqueceu do break
   case 2:
       fazOutraCoisa();
       break.
    default:
       fazUmaTerceiraCoisa();
       break;
}

Isso fica equivalente ao código:

if (opcao == 1) {
   fazAlgo();
   fazOutraCoisa();
} else (if opcao == 2) {
   fazOutraCoisa();
} else {
   fazUmaTerceiraCoisa();
}

Não há como testar condições mais complexas no switch. Intervalos por exemplo. Quanto a ser mais legível, também tenho minhas dúvidas. Eu sempre preferi código com if, e o problema do break é um exemplo de como ele pode prejudicar a legibilidade.

Depois da existência do polimorfismo, o switch e ifs como esses praticamente desapareceram. Mas isso você só vai ver com um pouco mais de estudo na linguagem."

Entendi, entao enquanto ele nao encontrar o momento para parar, no caso 'break' ele nao iria parar ate cair no default, mesmo as condições dos cases abaixo serem false, correto?

Exatamente, e não é assim por acaso, o switch case foi projetado para funcionar dessa forma. Porém como o Vini finaliza, quase não se utiliza mais esse tipo de estrutura. Ela teve seu ápice, mas já caiu em desuso. Na programação procedural era bem útil.

Entendi. Muito obrigado Emerson e Carlos

Outra forma de voce parar o switch sem o break, é colocar um "return", assim ele vai retornar a função e parar o código naquele ponto, assim não executando os outros cases.

Apenas cuidado com utilizar um return para parar um switch ou um laço, pois além de interromper a execução, também sairá do método.

Já o break vai fazer apenas a interrupção da estrutura de controle em si, não interferindo com o resto da execução do método.