[PT-BR] O Novo `switch case` no Java 17 e 21

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: TRIANGLE
Error: The switch statement does not cover all possible values of the enum: TRIANGLE
Error: 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. .

原文链接:[PT-BR] O Novo `switch case` no Java 17 e 21

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
No one can change another. But one can be the reason for another to change.
没人能改变另一个人,但是某个人能成为一个人改变的原因
评论 抢沙发

请登录后发表评论

    暂无评论内容