Java em 2025: o que há de novo? Visão geral na prática
O Java continua se desenvolvendo ativamente, e 2025 não foi exceção. Os lançamentos do JDK 23 e 24 trouxeram as tão esperadas estabilizações de funções experimentais, além de vários recursos completamente novos que mudam radicalmente a abordagem de escrever código. Neste artigo, analisaremos as principais novidades com exemplos práticos, para que você possa aplicá-las imediatamente em seus projetos. Abordaremos threads virtuais (Project Loom), Pattern Matching aprimorado, novos recursos de Record e Sealed Classes, além de mudanças na API.
1. Threads Virtuais (Project Loom) — padrão de facto
As threads virtuais, que se tornaram estáveis no JDK 21, em 2025 se transformaram na principal ferramenta para aplicações servidoras de alta carga. Elas permitem criar milhões de threads leves sem sobrecarregar o sistema operacional. A principal vantagem é a simplicidade: o código parece síncrono, mas funciona de forma assíncrona.
Exemplo: Cliente HTTP de alta carga
Suponha que você precise enviar 10.000 requisições HTTP. Com threads clássicas, isso causaria OutOfMemoryError ou enormes custos indiretos. Com threads virtuais, a tarefa é resolvida de forma elegante:
import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.URI;import java.util.concurrent.Executors;import java.util.stream.IntStream;
public class VirtualThreadsExample { public static void main(String[] args) throws Exception { var client = HttpClient.newHttpClient();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10_000).forEach(i -> { executor.submit(() -> { var request = HttpRequest.newBuilder() .uri(URI.create("https://httpbin.org/delay/1")) .build(); try { var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Requisição " + i + " concluída, status: " + response.statusCode()); } catch (Exception e) { System.err.println("Erro: " + e.getMessage()); } }); }); } // executor.close() aguarda a conclusão de todas as threads }}O que mudou em 2025? Melhor integração com sockets e bancos de dados. Agora, as threads virtuais funcionam corretamente com a maioria dos drivers JDBC populares (por exemplo, PostgreSQL) sem necessidade de modificação. Também surgiu a possibilidade de definir agendadores personalizados (ForkJoinPool) para ajuste fino de desempenho.
2. Pattern Matching — versão final e novos padrões
O Pattern Matching para switch e instanceof em 2025 atingiu a maturidade total. A principal novidade é o suporte a record patterns e guarded patterns (padrões condicionais). Isso permite escrever código muito conciso e seguro para analisar estruturas de dados complexas.
Exemplo: Análise de estrutura semelhante a JSON
sealed interface Shape permits Circle, Rectangle, Triangle {}record Circle(double radius) implements Shape {}record Rectangle(double width, double height) implements Shape {}record Triangle(double base, double height) implements Shape {}
public class PatternMatchingExample { public static double calculateArea(Shape shape) { return switch (shape) { case Circle c -> Math.PI * c.radius() * c.radius(); case Rectangle r -> r.width() * r.height(); // Guarded pattern: verifica se o triângulo não é degenerado case Triangle t when t.base() > 0 && t.height() > 0 -> 0.5 * t.base() * t.height()