Instrução Java Switch
1. Visão geral
Neste tutorial, aprenderemos o que é a instruçãoswitch e como usá-la.
A instruçãoswitch nos permite substituir várias construçõesif-else aninhadas e, assim, melhorar a legibilidade de nosso código.
Switch evoluiu com o tempo - novos tipos suportados foram adicionados, particularmente em Java 5 e 7. Além disso, ele continua a evoluir - expressõesswitch provavelmente serão introduzidas no Java 12.
A seguir, daremos alguns exemplos de código para demonstrar o uso da instruçãoswitch, a função da instruçãobreak, os requisitos para os valores de argumentoswitch /case e a comparação deStrings na instruçãoa switch.
Vamos passar para o exemplo.
2. Exemplo de Uso
Digamos que temos as seguintes instruçõesif-else aninhadas:
public String exampleOfIF(String animal) {
String result;
if (animal.equals("DOG") || animal.equals("CAT")) {
result = "domestic animal";
} else if (animal.equals("TIGER")) {
result = "wild animal";
} else {
result = "unknown animal";
}
return result;
}
O código acima não parece bom e seria difícil de manter e raciocinar sobre ele. Para melhorar a legibilidade, poderíamos usar uma instruçãoswitch aqui:
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
result = "domestic animal";
break;
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
Conforme mostrado acima, comparamos o argumentoswitchanimal com os diversos valorescase. Se nenhum dos valorescase for igual ao argumento, então o bloco sob o rótulodefault é executado.
Simplificando, a instruçãobreak é usada para sair de uma instruçãoswitch.
3. A declaraçãobreak
Embora a maioria das instruçõesswitch na vida real implique que apenas um dos blocoscase deve ser executado, a instruçãothe break é necessária para sair deswitch após a conclusão do bloco.
Se esquecermos de escrever umbreak, os blocos abaixo serão executados.
Para demonstrar isso, vamos omitir as instruçõesbreak e adicionar a saída ao console para cada bloco:
public String forgetBreakInSwitch(String animal) {
switch (animal) {
case "DOG":
System.out.println("domestic animal");
default:
System.out.println("unknown animal");
}
}
Vamos executar este códigoforgetBreakInSwitch (“DOG”),e verificar a saída para provar que todos os blocos foram executados:
domestic animal
unknown animal
Portanto, devemos ter cuidado e adicionar instruçõesbreak no final de cada bloco, a menos que haja necessidade de passar para o código no próximo rótulo.
O único bloco em quebreak não é necessário é o último, mas adicionarbreak ao último bloco torna o código menos sujeito a erros.
Também podemos aproveitar esse comportamento paraomit break when we want the same code executed for several case statements.. Vamos reescrever o exemplo da seção anterior agrupando os 2 primeiros casos:
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
4. Argumentoswitch e valorescase
Agora vamos discutir os tipos permitidos de argumentoswitch e valorescase, os requisitos para eles e como a instruçãoswitch funciona com Strings.
4.1. Tipos de dados
Não podemos comparar todos os tipos de objetos e primitivos na instruçãoswitch. A switch works only with four primitives and their wrappers, as well as with the enum type and the String class:
-
byte eByte
-
short eShort
-
int eInteger
-
char eCharacter
-
enum
-
Corda
O tipoString está disponível na instruçãoswitch começando com Java 7.
O tipoenum foi introduzido no Java 5 e está disponível na instruçãoswitch desde então.
As classes de wrapper também estão disponíveis desde o Java 5.
Obviamente, o argumentoswitche os valorescase devem ser do mesmo tipo.
4.2. No null Values
We can’t pass the null value as an argument to a switch statement. Se fizermos isso, o programa irá lançarNullPointerException, usando nosso primeiroswitch example:
@Test(expected=NullPointerException.class)
public void whenSwitchAgumentIsNull_thenNullPointerException() {
String animal = null;
Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
Claro, não podemos passarnull como um valor para o rótulocase de uma instruçãoswitch. Se fizermos isso, o código não será compilado.
4.3. Valores deCase como constantes de tempo de compilação
Se tentarmos substituir o valor do casoDOG pela variáveldog , o código não será compilado até que marquemos a variáveldog comofinal:
final String dog="DOG";
String cat="CAT";
switch (animal) {
case dog: //compiles
result = "domestic animal";
case cat: //does not compile
result = "feline"
}
4.4. String Comparação
Se uma instruçãoswitch usasse o operador de igualdade para comparar strings, não poderíamos comparar um argumentoString criado com o operadornew para um valor de casoString corretamente.
Felizmente, oswitch operator uses the equals() method under the hood.
Vamos demonstrar isso:
@Test
public void whenCompareStrings_thenByEqual() {
String animal = new String("DOG");
assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
5. Nova expressãoswitch
Java 12 está disponível e com ele a visualização de um novo recurso - uma expressãoswitch menos detalhada.
Para habilitá-lo, precisamos passar–enable-preview para o compilador.
Vamos dar uma olhada:
var month = JUN;
var value = switch(month) {
case JAN, JUN, JUL -> 3;
case FEB, SEP, OCT, NOV, DEC -> 1;
case MAR, MAY, APR, AUG -> 2;
};
System.out.println(value); // 3
Para aproveitar a nova sintaxe, não usamos mais dois pontos, mas o operador conhecido nas Lambda Expressions. Observe a falta da palavra-chavebreak e que os casos de falha não estão acontecendo.
Mas ainda há a possibilidade de obter controle refinado sobre o que está acontecendo no lado direito da expressão usando blocos de código. Nesse caso, precisamosbreak manualmente e especificar um valor de retorno:
public static void switchLocalVariable() {
var month = Month.AUG;
int i = switch (month){
case JAN,JUN, JUL -> 3;
case FEB,SEP, OCT, NOV, DEC -> 1;
case MAR,MAY, APR, AUG -> {
int j = month.toString().length() * 4;
break j;
}
};
System.out.println(i); //12
}
6. Conclusão
Neste tutorial, aprendemos as sutilezas do uso da instruçãoswitch em Java. Podemos decidir se usarswitch com base na legibilidade e no tipo dos valores comparados.
A instrução switch é um bom candidato para casos em que temos um número limitado de opções em um conjunto predefinido (por exemplo: dias da semana). Caso contrário, teríamos que modificar o código cada vez que um novo valor fosse adicionado ou removido, o que pode não ser viável. Para esses casos, devemos considerar outras abordagens, comopolymorphism ou outros padrões de design comoCommand.
Como sempre, o código completo está disponívelover on GitHub.