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. |
