Tal como uma instrução if/else, uma instrução switch permite-te alterar o fluxo do programa ao executar código de forma condicional.
A diferença é que uma instrução switch só pode comparar o valor de uma expressão primitiva ou de uma string com valores constantes predefinidos.
Há algumas palavras-chave úteis quando usas uma instrução switch.
switch: esta palavra-chave permite-te declarar a estrutura da instrução switch.
É seguida da expressão ou da variável que vai fazer o resultado mudar.case: vais usar esta para declarar as diferentes possibilidades do resultado.break: a palavra-chave break é muito útil para parar a execução da instrução switch no fim do fluxo pretendido.
Se te esqueceres dela, o programa continua e pode dar origem a resultados inesperados.default: como o nome indica, usa-a como resultado por omissão quando nenhum dos outros casos corresponde ao resultado da tua expressão.Na forma mais simples, testam uma expressão primitiva ou uma string e tomam uma decisão com base no seu valor. Por exemplo:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
A partir do Java 14 (antes disponível como pré-visualização no Java 12 e 13) é possível usar a implementação «melhorada» do switch.
Tens a possibilidade de atribuir vários valores a um único case.
Numa instrução switch tradicional podes usar o fall-through. No exemplo seguinte, case 1 e case 3 executam o mesmo código.
Isto acontece porque o case 1 não usa a palavra-chave break.
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
Numa switch expression melhorada podes atribuir diretamente vários valores a um case.
Vê o exemplo seguinte:
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
Agora podes escrever uma switch-statement ou uma switch expression.
Qual é a diferença?
Basicamente, uma instrução espera uma lógica estrita, ao passo que uma expressão pode devolver um valor.
Em vez de:
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
Podes fazer:
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
O yield funciona como um return, mas é para expressões switch.
Como o yield termina a expressão, o break não é necessário aqui.
Outra diferença entre instruções switch e expressões switch: nas expressões switch tens obrigatoriamente de cobrir todos os casos.
Ou tendo um case para todos os valores possíveis, ou usando um caso default.
Podes usar -> em vez de :.
O -> permite-te não incluir a palavra-chave break.
Podes usar as duas notações, mas numa instrução switch tens de te cingir a uma só.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
O âmbito.
O switch tradicional pode levar a comportamentos inesperados por causa do seu âmbito, já que há apenas um âmbito para todo o switch.
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
Este exemplo não funciona porque message é declarada duas vezes no switch.
Poderia resolver-se assim:
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
Já que as {} delimitam o âmbito do case.
No entanto, não é intuitivo, porque as {} não são obrigatórias.
Mas se usares a nova notação ->, esta tem de ser seguida de uma destas opções: uma única instrução/expressão, uma instrução throw ou um bloco {}.
Acabou a confusão!
Podes encontrar mais informações sobre o switch melhorado em este artigo e este outro, juntamente com a documentação oficial da Oracle.
Para além disso, foi adicionada no Java 21 uma funcionalidade chamada Guarded Patterns, que te permite fazer verificações no próprio rótulo do case.
String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
case "Saturday", "Sunday" -> "Weekend";
default -> "Unknown";
};
Podes encontrar mais informações sobre a expressão switch no Java 21 em este blog