Disclaimer: Esse post apareceu primeiro no meu bluesky.
O switch case
no Java 17 e 21 trouxe várias melhorias que vão facilitar a vida de quem programa em Java. De compile-time errors ao yield
, temos bastante coisa bacana pra explorar! Vamos conferir as principais novidades!
1. Esqueça o default
!
Agora o compilador avisa se você esquecer um case, tornando o código mais seguro. Se todos os valores possíveis forem cobertos, você pode deixar de lado o default
. O melhor de tudo? Compile-time errors garantem que nenhum cenário fique de fora!
Vamos dar uma olhada em um exemplo que mostra um erro de compilação quando um valor é adicionado à enum, mas não é coberto no switch case
.
<span>enum</span> <span>Shape</span> <span>{</span> <span>CIRCLE</span><span>,</span> <span>SQUARE</span> <span>}</span><span>// Depois adicionamos TRIANGLE à enum</span><span>enum</span> <span>Shape</span> <span>{</span> <span>CIRCLE</span><span>,</span> <span>SQUARE</span><span>,</span> <span>TRIANGLE</span> <span>}</span><span>Shape</span> <span>shape</span> <span>=</span> <span>...;</span><span>switch</span> <span>(</span><span>shape</span><span>)</span> <span>{</span><span>case</span> <span>CIRCLE</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a circle!"</span><span>);</span><span>case</span> <span>SQUARE</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a square!"</span><span>);</span><span>}</span><span>enum</span> <span>Shape</span> <span>{</span> <span>CIRCLE</span><span>,</span> <span>SQUARE</span> <span>}</span> <span>// Depois adicionamos TRIANGLE à enum</span> <span>enum</span> <span>Shape</span> <span>{</span> <span>CIRCLE</span><span>,</span> <span>SQUARE</span><span>,</span> <span>TRIANGLE</span> <span>}</span> <span>Shape</span> <span>shape</span> <span>=</span> <span>...;</span> <span>switch</span> <span>(</span><span>shape</span><span>)</span> <span>{</span> <span>case</span> <span>CIRCLE</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a circle!"</span><span>);</span> <span>case</span> <span>SQUARE</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a square!"</span><span>);</span> <span>}</span>enum Shape { CIRCLE, SQUARE } // Depois adicionamos TRIANGLE à enum enum Shape { CIRCLE, SQUARE, TRIANGLE } Shape shape = ...; switch (shape) { case CIRCLE -> System.out.println("It's a circle!"); case SQUARE -> System.out.println("It's a square!"); }
Enter fullscreen mode Exit fullscreen mode
Aqui, o compilador irá lançar um erro dizendo que o valor TRIANGLE
não foi tratado no switch
. Isso acontece porque todos os valores da enum precisam ser cobertos no switch case
— garantindo que nenhum cenário fique de fora e mantendo o código mais robusto e seguro! Sem o default
, você terá certeza de que todos os casos estão sendo tratados.
Erro de compilação:
Error: The switch statement does not cover all possible values of the enum: TRIANGLEError: The switch statement does not cover all possible values of the enum: TRIANGLEError: The switch statement does not cover all possible values of the enum: TRIANGLE
Enter fullscreen mode Exit fullscreen mode
2. Yield!
Agora o switch
pode retornar valores com yield
, deixando o código mais limpo e expressivo. Esqueça os retornos confusos e aproveite a simplicidade. O resultado? Código mais claro e direto!
Exemplo com yield
<span>String</span> <span>message</span> <span>=</span> <span>switch</span> <span>(</span><span>day</span><span>)</span> <span>{</span><span>case</span> <span>MONDAY</span> <span>-></span> <span>{</span><span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Starting the week!"</span><span>);</span><span>yield</span> <span>"Back to work!"</span><span>;</span><span>}</span><span>case</span> <span>FRIDAY</span> <span>-></span> <span>{</span><span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Weekend is coming!"</span><span>);</span><span>yield</span> <span>"Almost there!"</span><span>;</span><span>}</span><span>case</span> <span>SATURDAY</span><span>,</span> <span>SUNDAY</span> <span>-></span> <span>"Enjoy the weekend!"</span><span>;</span><span>};</span><span>String</span> <span>message</span> <span>=</span> <span>switch</span> <span>(</span><span>day</span><span>)</span> <span>{</span> <span>case</span> <span>MONDAY</span> <span>-></span> <span>{</span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Starting the week!"</span><span>);</span> <span>yield</span> <span>"Back to work!"</span><span>;</span> <span>}</span> <span>case</span> <span>FRIDAY</span> <span>-></span> <span>{</span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Weekend is coming!"</span><span>);</span> <span>yield</span> <span>"Almost there!"</span><span>;</span> <span>}</span> <span>case</span> <span>SATURDAY</span><span>,</span> <span>SUNDAY</span> <span>-></span> <span>"Enjoy the weekend!"</span><span>;</span> <span>};</span>String message = switch (day) { case MONDAY -> { System.out.println("Starting the week!"); yield "Back to work!"; } case FRIDAY -> { System.out.println("Weekend is coming!"); yield "Almost there!"; } case SATURDAY, SUNDAY -> "Enjoy the weekend!"; };
Enter fullscreen mode Exit fullscreen mode
Aqui, o yield
permite que retornemos valores diretamente no switch sem complicações.
3. Suporte para Enums e Sealed Types
O suporte para enums
e sealed types
no switch case
foi melhorado! Agora, enums
são tratados de maneira mais fluida, e com sealed types
, podemos garantir que todos os subtipos sejam cobertos no switch, tornando o código mais previsível e seguro.
Exemplo com Sealed Types
<span>sealed</span> <span>interface</span> <span>Shape</span> <span>permits</span> <span>Circle</span><span>,</span> <span>Square</span> <span>{</span><span>// Pode adicionar métodos ou propriedades comuns</span><span>}</span><span>final</span> <span>class</span> <span>Circle</span> <span>implements</span> <span>Shape</span> <span>{</span><span>// Implementação da classe Circle</span><span>}</span><span>final</span> <span>class</span> <span>Square</span> <span>implements</span> <span>Shape</span> <span>{</span><span>// Implementação da classe Square</span><span>}</span><span>Shape</span> <span>shape</span> <span>=</span> <span>...;</span><span>switch</span> <span>(</span><span>shape</span><span>)</span> <span>{</span><span>case</span> <span>Circle</span> <span>c</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a circle with radius: "</span> <span>+</span> <span>c</span><span>.</span><span>getRadius</span><span>());</span><span>case</span> <span>Square</span> <span>s</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a square with side: "</span> <span>+</span> <span>s</span><span>.</span><span>getSide</span><span>());</span><span>}</span><span>sealed</span> <span>interface</span> <span>Shape</span> <span>permits</span> <span>Circle</span><span>,</span> <span>Square</span> <span>{</span> <span>// Pode adicionar métodos ou propriedades comuns</span> <span>}</span> <span>final</span> <span>class</span> <span>Circle</span> <span>implements</span> <span>Shape</span> <span>{</span> <span>// Implementação da classe Circle</span> <span>}</span> <span>final</span> <span>class</span> <span>Square</span> <span>implements</span> <span>Shape</span> <span>{</span> <span>// Implementação da classe Square</span> <span>}</span> <span>Shape</span> <span>shape</span> <span>=</span> <span>...;</span> <span>switch</span> <span>(</span><span>shape</span><span>)</span> <span>{</span> <span>case</span> <span>Circle</span> <span>c</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a circle with radius: "</span> <span>+</span> <span>c</span><span>.</span><span>getRadius</span><span>());</span> <span>case</span> <span>Square</span> <span>s</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"It's a square with side: "</span> <span>+</span> <span>s</span><span>.</span><span>getSide</span><span>());</span> <span>}</span>sealed interface Shape permits Circle, Square { // Pode adicionar métodos ou propriedades comuns } final class Circle implements Shape { // Implementação da classe Circle } final class Square implements Shape { // Implementação da classe Square } Shape shape = ...; switch (shape) { case Circle c -> System.out.println("It's a circle with radius: " + c.getRadius()); case Square s -> System.out.println("It's a square with side: " + s.getSide()); }
Enter fullscreen mode Exit fullscreen mode
Neste exemplo, Shape
é uma sealed interface
e garantimos que todas as possíveis subclasses de Shape
(no caso, Circle
e Square
) sejam cobertas no switch case
. O compilador ajuda a garantir que não deixemos nenhum caso de fora, aumentando a segurança do código.
4. Desconstrução de Tipos com Pattern Matching
E não para por aí! Também temos a desconstrução de tipos no switch case
, o que nos permite fazer pattern matching
diretamente nos objetos. Isso torna o código mais poderoso e flexível.
Exemplo com Pattern Matching
<span>switch</span> <span>(</span><span>obj</span><span>)</span> <span>{</span><span>case</span> <span>Point</span><span>(</span><span>int</span> <span>x</span><span>,</span> <span>int</span> <span>y</span><span>)</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Point with coordinates: ("</span> <span>+</span> <span>x</span> <span>+</span> <span>", "</span> <span>+</span> <span>y</span> <span>+</span> <span>")"</span><span>);</span><span>case</span> <span>Circle</span> <span>c</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Circle with radius: "</span> <span>+</span> <span>c</span><span>.</span><span>getRadius</span><span>());</span><span>}</span><span>switch</span> <span>(</span><span>obj</span><span>)</span> <span>{</span> <span>case</span> <span>Point</span><span>(</span><span>int</span> <span>x</span><span>,</span> <span>int</span> <span>y</span><span>)</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Point with coordinates: ("</span> <span>+</span> <span>x</span> <span>+</span> <span>", "</span> <span>+</span> <span>y</span> <span>+</span> <span>")"</span><span>);</span> <span>case</span> <span>Circle</span> <span>c</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Circle with radius: "</span> <span>+</span> <span>c</span><span>.</span><span>getRadius</span><span>());</span> <span>}</span>switch (obj) { case Point(int x, int y) -> System.out.println("Point with coordinates: (" + x + ", " + y + ")"); case Circle c -> System.out.println("Circle with radius: " + c.getRadius()); }
Enter fullscreen mode Exit fullscreen mode
O poder do pattern matching nos dá um controle maior sobre os tipos!
Fiquem Ligados!
Em breve, vamos falar sobre Sealed Types e como, junto com o novo switch
, eles abrem um novo paradigma de programação no Java. .
暂无评论内容