O Java evoluiu profundamente nos últimos anos. Quem parou no Java 8 costuma se surpreender com a quantidade de melhorias em linguagem, performance, APIs e modelo de releases. Neste conteúdo, apresentamos uma visão geral das versões do Java e percorremos as principais mudanças introduzidas em cada versão LTS, da 8 até a 25.
Entendendo as versões do Java
Desde 2017, o Java adotou um ciclo de lançamentos previsível, com novas versões a cada seis meses. Essas versões se dividem em dois tipos.
Versões não LTS
As versões não LTS são lançadas a cada seis meses e recebem atualizações por um período curto. Elas funcionam como um laboratório para novas funcionalidades, permitindo que a comunidade teste recursos antes de sua consolidação. Normalmente, não são adotadas em produção corporativa.
Versões LTS (Long-Term Support)
As versões LTS são lançadas aproximadamente a cada dois anos e recebem suporte prolongado, incluindo correções de bugs e atualizações de segurança. São as versões mais utilizadas em ambientes corporativos e em sistemas de longa vida. Exemplos clássicos são Java 8, 11, 17, 21 e 25.
Na prática, a maioria das empresas ignora as versões intermediárias e realiza atualizações diretamente de uma LTS para outra.
Java 8 (2014)
O Java 8 foi um divisor de águas e, por muitos anos, tornou-se o padrão dominante do mercado.
Entre as principais mudanças estão as expressões lambda, a Streams API, que introduziu um estilo funcional para processamento de coleções, os métodos default em interfaces, a classe Optional para lidar melhor com valores nulos e a nova API de data e hora (java.time).
O impacto prático dessas mudanças foi um código mais expressivo, menos verboso e com forte incentivo a um estilo funcional.
import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; class Java8Demo { interface Auditoria { default void log(String msg) { System.out.println("[AUDIT] " + msg); } } static Optional<String> primeiraPalavraLonga(List<String> palavras) { return palavras.stream() .map(String::trim) .filter(p -> p.length() >= 5) .findFirst(); } public static void main(String[] args) { List<String> dados = Arrays.asList(" java ", " spring ", "api", "cloud"); List<String> upper = dados.stream() .map(s -> s.trim().toUpperCase()) .collect(Collectors.toList()); System.out.println(upper); String valor = primeiraPalavraLonga(dados) .orElse("(nenhuma palavra com 5+ chars)"); System.out.println(valor); LocalDate hoje = LocalDate.now(); System.out.println("Hoje: " + hoje); } }
Java 11 (2018)
O Java 11 foi a primeira versão LTS após a adoção do novo ciclo de releases.
Essa versão consolidou diversas mudanças iniciadas no Java 9 e 10, como a remoção de módulos Java EE e CORBA do JDK, a introdução da nova API HTTP Client como padrão, melhorias na classe String, suporte ao uso de var em parâmetros lambda e a possibilidade de executar arquivos .java diretamente sem compilação explícita.
O impacto prático foi um JDK mais enxuto, moderno e alinhado com aplicações web e serviços HTTP.
import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.List; class Java11Demo { public static void main(String[] args) throws Exception { String s = " \n Java 11 \n "; System.out.println("isBlank? " + s.isBlank()); System.out.println("lines: " + s.lines().toList()); System.out.println("strip: '" + s.strip() + "'"); List<String> nomes = List.of("ana", "bob", "carla"); nomes.stream() .map((var n) -> n.toUpperCase()) .forEach(System.out::println); HttpClient client = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("https://example.com")) .GET() .build(); HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString()); System.out.println("Status: " + res.statusCode()); } }
Java 17 (2021)
O Java 17 é considerada uma das versões LTS mais importantes da história recente da linguagem.
Entre seus destaques estão os records, que reduzem drasticamente o boilerplate de classes de dados, as sealed classes, que permitem maior controle sobre hierarquias de herança, o pattern matching para instanceof e uma série de melhorias de performance e limpeza de APIs legadas.
O impacto prático foi uma grande evolução na modelagem de domínio e na legibilidade do código.
record Money(String currency, long cents) { Money { if (currency == null || currency.isBlank()) { throw new IllegalArgumentException("currency"); } } } sealed interface Payment permits Pix, CreditCard { Money amount(); } record Pix(Money amount, String key) implements Payment {} record CreditCard(Money amount, String last4) implements Payment {} class Java17Demo { static String describe(Object obj) { if (obj instanceof Money m) { return m.currency() + " " + (m.cents() / 100.0); } return "(unknown)"; } public static void main(String[] args) { Payment p = new Pix(new Money("BRL", 1299), "chave@pix"); System.out.println(describe(p.amount())); } }
Java 21 (2023)
O Java 21 consolidou recursos modernos que estiveram em incubação por várias versões.
O principal destaque é a introdução das virtual threads, que simplificam drasticamente o modelo de concorrência e permitem aplicações altamente escaláveis. Além disso, houve avanços importantes em pattern matching, melhorias no switch, novas coleções sequenciais e evoluções significativas no Garbage Collector.
Na prática, o Java passou a oferecer um modelo de concorrência mais simples, eficiente e adequado para aplicações modernas e cloud-native.
import java.util.concurrent.Executors; class Java21Demo { static void ioSimulada(int id) { try { Thread.sleep(50); System.out.println("OK " + id + " em " + Thread.currentThread()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } static String categoriaHttp(int status) { return switch (status) { case 200, 201, 204 -> "sucesso"; case 400, 401, 403, 404 -> "cliente"; case 500, 502, 503 -> "servidor"; default -> "outro"; }; } public static void main(String[] args) { try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 1; i <= 10; i++) { int id = i; executor.submit(() -> ioSimulada(id)); } } System.out.println(categoriaHttp(200)); System.out.println(categoriaHttp(503)); } }
Java 25 (2025)
O Java 25 é a versão LTS mais recente e representa a maturidade da visão moderna da plataforma.
Essa versão traz refinamentos nas virtual threads, avanços adicionais em concorrência estruturada, melhorias contínuas em pattern matching e switch, além de ganhos relevantes de performance da JVM, especialmente em ambientes distribuídos e em nuvem.
O impacto prático é o fortalecimento do Java como uma plataforma moderna, escalável e preparada para sistemas de alta complexidade, sem abrir mão da compatibilidade com código legado.
import java.time.Duration; import java.util.concurrent.*; record WorkResult(String jobId, boolean ok, Duration elapsed) {} class Java25StyleDemo { static WorkResult runJob(String jobId) { long start = System.nanoTime(); try { Thread.sleep(30); return new WorkResult(jobId, true, Duration.ofNanos(System.nanoTime() - start)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return new WorkResult(jobId, false, Duration.ofNanos(System.nanoTime() - start)); } } static String statusLine(WorkResult r) { return switch (r.ok()) { case true -> "JOB " + r.jobId() + " OK em " + r.elapsed().toMillis() + "ms"; case false -> "JOB " + r.jobId() + " FAIL em " + r.elapsed().toMillis() + "ms"; }; } public static void main(String[] args) throws Exception { try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) { Future<WorkResult> a = exec.submit(() -> runJob("A")); Future<WorkResult> b = exec.submit(() -> runJob("B")); System.out.println(statusLine(a.get())); System.out.println(statusLine(b.get())); } } }
Resumo das versões LTS do Java
| Versão | Ano | Visão Geral |
|---|---|---|
| Java 8 | 2014 | Introduziu programação funcional, streams e a nova API de datas, mudando profundamente o estilo de código Java. |
| Java 11 | 2018 | Consolidou o novo ciclo de releases, modernizou APIs e tornou o JDK mais enxuto. |
| Java 17 | 2021 | Evoluiu a modelagem de domínio com records e sealed classes, além de grandes ganhos de performance. |
| Java 21 | 2023 | Transformou o modelo de concorrência com virtual threads e consolidou recursos modernos. |
| Java 25 | 2025 | Refinou a concorrência e performance, reforçando o Java como plataforma moderna e cloud-native. |

