Setembro de 2025 está terminando e, com ele, o Java 25 (LTS), finalmente aquela versão “para levar pra produção sem dor de cabeça”. Confesso: eu quase não acompanho os releases não-LTS. Resultado? Um combo acumulado de Java 22, 23, 24 e 25 para digerir de uma vez só. Se você está igual, respira: este é o guia de sobrevivência pra entender o que realmente mudou desde a última LTS (Java 21) e decidir o que vale priorizar no seu ambiente.
Pra calibrar a expectativa: nesse período pintaram dezenas de JEPs, mas só uma parte virou funcionalidade definitiva. O resto ainda está em preview/incubation ou acabou descartado. Traduzindo: dá pra fechar esse “livro de pendências” sem precisar virar noite, aqui você encontra tudo resumido em blocos práticos.
O versionamento do Java
Quando a gente olha a linha do tempo do Java, dá pra ver as versões com suporte e até quando podemos contar com suas atualizações:
Versão | Fim do suporte |
---|---|
Java 25 | Setembro de 2030 |
Java 21 | Dezembro de 2029 |
Java 17 | Outubro de 2027 |
Java 11 | Outubro de 2027 |
Java 8 | Novembro de 2026 |
O modelo de versionamento pode parecer meio esquisito. Por exemplo: o Java 22 foi aposentado no mesmo dia em que o 23 saiu da concessionária. É assim mesmo: versões não-LTS são como modelos especiais de carro, ficam pouco tempo no mercado, servem pra testar novos recursos, mas logo dão lugar ao próximo lançamento. Se você comprou um desses, logo precisa pensar em trocar.
Já as versões LTS (Long Term Support) são os modelos de linha, que a montadora garante peça e manutenção por anos. Na prática, isso significa receber atualizações de segurança e correções de bugs por muito mais tempo. É por isso que, em sistemas de produção, quase sempre se aposta no LTS: é como escolher um carro popular que qualquer oficina sabe arrumar, em vez de um protótipo cheio de tecnologia nova que pode te deixar parado no acostamento.
As atualizações acumulativos
Aqui vamos revisar o pacote de mudanças do Java 22 até o Java 25, mas com um filtro importante: só entram as funcionalidades que já são definitivas. Ou seja, vamos deixar de fora tudo que ainda está em preview ou incubation, porque não são recomendadas para uso em produção.
Mas antes, vale um parêntese: o que é uma JEP?
JEP significa JDK Enhancement Proposal (Proposta de Melhoria do JDK). É o documento oficial onde a comunidade do OpenJDK descreve e justifica uma mudança na linguagem ou na plataforma. Uma JEP pode ser:
- Definitiva → já aprovada, implementada e pronta pra produção.
- Preview/Incubation → disponível para testes, mas ainda sujeita a mudanças.
- Rejeitada ou Retirada → proposta que não avançou.
Neste guia, vou focar apenas nas JEPs definitivas, porque são elas que realmente impactam quem precisa manter sistemas rodando em produção com segurança.
🧹 Garbage Collectors
O Garbage Collector (GC) é quem cuida da limpeza de memória na JVM. Ele identifica objetos que não têm mais uso e libera esse espaço, evitando os temidos memory leaks. Entre o Java 22 e o 25, várias melhorias chegaram para reduzir pausas, melhorar desempenho e evoluir coletores já existentes.
JEP 423: Fixação de Regiões para o G1 (Java 22)
O G1 ganhou a capacidade de “prender” (pin) regiões do heap enquanto código nativo (JNI) está em áreas críticas. Na prática, isso permite que o GC continue trabalhando normalmente nas outras regiões sem precisar parar tudo.
JEP 474: ZGC - Modo geracional como padrão (Java 23)
O ZGC agora roda em modo geracional por padrão. O antigo modo não-geracional foi marcado como deprecado e deve ser removido em versões futuras.
-
Antes: quem usava
-XX:+UseZGC
ativava o ZGC clássico (não-geracional). - Agora: o mesmo comando já ativa o ZGC Geracional, que separa objetos novos dos de longa duração, otimizando coleta de lixo.
JEP 475: Expansão tardia das barreiras do G1 (Java 24)
O G1 ganhou uma simplificação no jeito que lida com as suas barreiras (os pontos de anotação de acessos à memória). Agora, a expansão dessas barreiras no compilador C2 acontece apenas na fase final de emissão de código.
- Antes: o compilador expandia essas instruções mais cedo, o que aumentava custo de compilação JIT em tempo e memória.
- Agora: com a expansão adiada, o compilador gasta menos recursos no startup e durante o aquecimento da aplicação.
JEP 490: ZGC: Remover o modo não-geracional (Java 24)
O ZGC completa a transição: o modo não-geracional foi removido de vez.
-
Antes: era possível escolher entre
-XX:+ZGenerational
e-XX:-ZGenerational
para ligar ou desligar o modo. -
Agora: ao usar apenas
-XX:+UseZGC
, você sempre roda o ZGC Geracional. As flags antigas continuam aceitas, mas só geram aviso de obsolescência.
JEP 521: Shenandoah geracional (Java 25)
O Shenandoah também entrou na onda geracional. O modo, que antes era experimental, agora é promovido a recurso de produto.
-
Antes: precisava usar
-XX:+UnlockExperimentalVMOptions
para habilitar. - Agora: pode ser ativado diretamente, sem desbloquear flags experimentais.
Importante: o padrão ainda é o Shenandoah de uma geração. Para usar o geracional, é preciso habilitar explicitamente:
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
💻 JVM
A JVM precisa carregar, ligar e otimizar classes o mais rápido possível. Isso reduz o tempo de inicialização (startup) e deixa a performance mais previsível em produção. Nos últimos releases, o foco foi acelerar esse arranque e também preparar terreno para otimizações antecipadas (AOT).
JEP 458: Executar Programas de Código-Fonte Multiarquivo (Java 22)
Agora é possível executar, diretamente com o comando java
, um programa que tenha vários arquivos .java
, sem precisar compilar antes com javac
.
- Antes: só era possível rodar scripts de um único arquivo.
- Agora: você pode organizar seu código em múltiplos arquivos e ainda assim rodar de forma imediata.
Limite: esse recurso não resolve gerenciamento de dependências externas, a ideia aqui é acelerar o desenvolvimento inicial, não substituir ferramentas de build.
JEP 491: Sincronizar threads virtuais sem fixação (Java 24)
Essa JEP elimina quase todos os casos em que threads virtuais ficavam “presas” (pinning) ao usar synchronized
.
-
Antes: ao bloquear dentro de métodos/blocos sincronizados ou em
Object.wait()
, a thread virtual mantinha ocupada a thread de plataforma, limitando a escalabilidade. - Agora: nesses cenários, a thread virtual libera a thread de plataforma para que outras possam avançar.
Atenção: ainda pode haver fixação ao entrar ou voltar de código nativo (JNI/FFM).
JEP 483: Carregamento e Vinculação de Classes Antecipados (AOT) (Java 24)
Essa JEP introduz um cache AOT (Ahead-of-Time) que guarda classes já lidas, analisadas, carregadas e vinculadas. Assim, em execuções seguintes, essas classes ficam “pré-prontas” logo no início.
- Como funciona: você roda uma execução de treinamento para gerar o cache. Depois, a JVM reaproveita esse cache em execuções futuras.
- Impacto prático: o tempo de startup melhora sensivelmente, sem precisar alterar código-fonte.
JEP 484: API de Arquivos de Classe (Java 24)
Essa JEP traz uma API oficial para lidar com arquivos de classe. A ideia é permitir que ferramentas e frameworks acompanhem as mudanças no formato de bytecode a cada release do JDK sem depender de bibliotecas externas que precisam ser atualizadas separadamente.
- Antes: cada ferramenta precisava de libs de terceiros (como ASM) para interpretar/gerar bytecode.
- Agora: a própria API do JDK oferece suporte direto.
JEP 493: Vinculação de imagens de tempo de execução sem JMODs (Java 24)
Essa JEP permite que o jlink
crie imagens de runtime sem precisar dos arquivos JMOD do JDK.
- Benefício direto: reduz em cerca de 25% o tamanho da distribuição do JDK quando essa opção é habilitada na construção.
- Limitação: essa funcionalidade é ativada em tempo de build do JDK, então nem todos os fornecedores vão disponibilizar.
JEP 514: Ergonomia de Linha de Comando para AOT (Java 25)
Essa JEP simplifica a criação de caches AOT (ahead-of-time), que ajudam a reduzir o tempo de startup das aplicações Java.
Antes (Java 24): era preciso seguir um fluxo em duas etapas para gerar e depois montar o cache AOT.
Agora (Java 25): você pode fazer tudo em uma única execução da JVM, por exemplo:
java -XX:AOTCacheOutput=meu-cache.aot MinhaApp.java
JEP 515: Ahead-of-Time Method Profiling (Java 25)
Essa JEP permite disponibilizar, já na inicialização da JVM, perfis de execução de métodos coletados em uma execução de treinamento e armazenados no cache AOT.
- Antes: o compilador JIT precisava observar a execução em tempo real para decidir quais métodos valiam a pena otimizar, o que aumentava o tempo de aquecimento (warmup).
- Agora: com os perfis já prontos no cache AOT, o JIT pode gerar código nativo desde o primeiro momento.
JEP 518: JFR: Amostragem Cooperativa (Java 25)
Essa JEP torna o JDK Flight Recorder (JFR) mais estável e confiável ao coletar amostras de pilha.
- Antes: o JFR podia andar na pilha de threads a qualquer momento, o que aumentava o risco de travamentos ou leituras inconsistentes, especialmente quando usado junto a GCs concorrentes como o ZGC.
- Agora: a amostragem passa a acontecer em safepoints, reduzindo esses riscos.
JEP 519: Cabeçalhos de Objetos Compactos (Java 25)
Essa JEP promove os Cabeçalhos de Objetos Compactos (introduzidos de forma experimental na JEP 450 / JDK 24) a recurso de produto.
- O que muda: o tamanho do cabeçalho de cada objeto é reduzido.
- Impacto prático: melhora a densidade de implantação e o uso de memória, especialmente em aplicações que lidam com muitos objetos pequenos.
- Limite: não é o padrão; precisa ser habilitado via flag da JVM. Nenhuma API ou código da aplicação precisa ser alterado.
JEP 520: JFR: Medição de Tempo e Rastreamento de Métodos (Java 25)
Essa JEP amplia o JDK Flight Recorder (JFR) com dois novos eventos:
-
jdk.MethodTiming
→ mede o tempo gasto por método. -
jdk.MethodTrace
→ registra a sequência de chamadas entre métodos.
📝 Linguagem
A linguagem Java também recebeu refinamentos para tornar o código mais conciso, expressivo e moderno. Essas melhorias ajudam a reduzir a verbosidade histórica e trazem novas formas de escrever programas.
JEP 454: API de Funções e Memória Externas (FFM) (Java 22)
Essa JEP entrega uma API oficial para:
- Chamar funções nativas (fora da JVM).
- Acessar memória externa com segurança.
Impacto prático: substitui em muitos cenários o frágil JNI, simplificando a integração com bibliotecas C/C++ e o trabalho com buffers off-heap. Isso melhora produtividade e desempenho em áreas como I/O, codecs, drivers e até ciência de dados.
JEP 456: Variáveis e Padrões Sem Nome (Java 22)
Essa JEP permite usar o sublinhado _
quando uma variável ou um componente de padrão é obrigatório pela sintaxe, mas você não vai usá-lo depois.
-
Onde usar: em
catch
,switch
com padrões,for
e lambdas. - Objetivo: reduzir “ruído” no código e deixar claro que aquela variável não tem utilidade real.
-
Detalhe importante: o
_
passou a ser uma palavra-chave, ou seja, não pode mais ser usado como identificador comum.
Impacto prático: código mais limpo, com menos variáveis “descartáveis” fingindo que seriam usadas.
💻 Exemplos: Antes da JEP 456 | Depois da JEP 456
JEP 467: Comentários de Documentação em Markdown (Java 23)
Agora o JavaDoc aceita comentários escritos em Markdown, além do tradicional HTML e das tags @
.
- Antes: a documentação precisava ser feita em HTML + tags, o que deixava tudo mais “engessado”.
- Agora: dá para escrever listas, títulos e links de forma mais natural com Markdown.
Impacto prático:
- Documentação mais legível direto no código.
- Menos atrito para escrever e manter comentários.
- Compatibilidade preservada: você pode misturar HTML, tags JavaDoc e Markdown sem problemas.
💻 Exemplos: Antes da JEP 467 | Depois da JEP 467
JEP 485: Stream Gatherers (Java 24)
Essa JEP adiciona o método Stream.gather(Gatherer)
e a classe utilitária Gatherers
, permitindo criar operações intermediárias personalizadas em streams.
-
Antes: para casos como janelas, varreduras incrementais ou deduplicação por critério, era preciso fazer “malabarismos” com
collect
e listas temporárias. - Agora: dá pra implementar essas operações direto no pipeline, de forma clara e reutilizável.
Impacto prático:
- Pipelines de stream mais legíveis e expressivos.
- Menos código extra e menos estruturas temporárias.
💻 Exemplos: Antes da JEP 485 | Depois da JEP 485
JEP 506: Valores de Escopo (Java 25)
Essa JEP introduz os valores de escopo, uma forma mais simples e segura de compartilhar dados imutáveis dentro da mesma thread e também com threads filhas (incluindo threads virtuais).
-
Antes: o recurso típico era o
ThreadLocal
, mas ele é difícil de raciocinar, tem custo maior e pode causar vazamentos de memória se não for bem gerenciado. - Agora: os valores de escopo oferecem uma alternativa mais clara e leve, funcionando muito bem em conjunto com concorrência estruturada.
Impacto prático:
- Código mais fácil de entender e manter.
- Menor custo para compartilhar dados entre chamadas e threads relacionadas.
- Evita armadilhas comuns do
ThreadLocal
.
💻 Exemplos: Antes da JEP 506 | Depois da JEP 506
JEP 511: Declarações de Importação de Módulo (Java 25)
Essa JEP permite importar, em uma única linha, todas as classes públicas dos pacotes exportados por um módulo, usando:
import module <nome>;
-
Antes: era necessário listar uma sequência longa de
import
, pacote por pacote. - Agora: basta importar o módulo inteiro, incluindo exportações transitivas.
Impacto prático:
- Código mais limpo, sem listas enormes de imports.
- Facilita o uso de APIs modulares, mesmo quando seu código não está dentro de um módulo, o
import module
funciona também em projetos não modularizados.
💻 Exemplos: Antes da JEP 511 | Depois da JEP 511
JEP 512: Arquivos de Fonte Compactos e main
de Instância (Java 25)
Essa JEP é uma das que mais simplificam o “Hello, World” em Java.
-
Antes: precisava declarar classe, método
main
estático, receberString[] args
e importar explicitamente. -
Agora:
- O
main
pode ser de instância (semstatic
e semString[] args
). - Você pode usar arquivos de fonte compactos, sem declarar a classe explicitamente.
- Há a classe utilitária
java.lang.IO
para E/S simples. - Os imports básicos do
java.base
vêm automáticos.
- O
Impacto prático:
- Muito menos cerimônia para escrever scripts e exemplos didáticos.
- Ideal para ensino e prototipagem, sem criar um dialeto separado da linguagem: é Java de verdade, só que mais enxuto.
💻 Exemplos: Antes da JEP 512 | Depois da JEP 512
JEP 513: Corpos de Construtores Flexíveis (Java 25)
Essa JEP permite escrever instruções antes de chamar super(...)
ou this(...)
dentro de um construtor.
-
Antes: qualquer lógica tinha que vir depois da chamada ao
super(...)
outhis(...)
. -
Agora: você pode incluir um prólogo no construtor, útil para:
- validar argumentos,
- calcular variáveis locais,
- inicializar campos ainda não atribuídos.
Regras importantes:
- No prólogo não é permitido usar
this
(não pode acessar campos nem chamar métodos de instância). - Também não dá pra chamar
super
, exceto para atribuir a campos declarados sem inicializador. - O restante da lógica continua no epílogo (após a chamada a
super
outhis
).
💻 Exemplos: Antes da JEP 513 | Depois da JEP 513
🔒 Segurança e Criptografia
Segurança continua sendo prioridade no JDK: desde remover mecanismos antigos até incluir algoritmos preparados para resistir até mesmo a ataques de computadores quânticos.
JEP 496: Mecanismo de Encapsulamento de Chaves baseado em reticulados modulares (ML-KEM) resistente a ataques quânticos (Java 24)
Essa JEP adiciona suporte ao ML-KEM (lattice-based, padronizado no FIPS 203) na API de KEM (Key Encapsulation Mechanism) do Java.
-
O que traz:
- Implementação do ML-KEM com parâmetros 512, 768 e 1024 (padrão: 768).
- Permite negociar chaves simétricas de forma resistente a ataques quânticos.
-
Impacto prático:
- Alternativa futura a ECDH ou RSA em cenários de troca de chaves.
- Ainda não há integração direta com TLS, pois isso depende da padronização externa.
Resultado: aplicações podem começar a experimentar algoritmos pós-quânticos sem depender de libs externas, preparando terreno para um futuro mais seguro.
💻 Exemplos: Antes da JEP 496 | Depois da JEP 496
JEP 497: Algoritmo de Assinatura Digital baseado em Reticulados Modulares (ML-DSA) resistente a ataques quânticos (Java 24)
Essa JEP implementa o ML-DSA (FIPS 204), um algoritmo de assinatura digital resistente a ataques de computadores quânticos.
-
APIs suportadas:
KeyPairGenerator
,Signature
eKeyFactory
. - Parâmetros disponíveis: ML-DSA-44, 65 (padrão) e 87.
Impacto prático:
- Permite assinar e verificar dados de forma segura mesmo em cenários futuros de computação quântica.
- Coloca o Java na vanguarda de algoritmos pós-quânticos já padronizados.
Limitações atuais:
- Ainda não há integração com JAR signing ou TLS, isso depende da evolução dos padrões externos.
- Também não há suporte a pre-hash ou context strings.
💻 Exemplos: Antes da JEP 497 | Depois da JEP 497
JEP 510: API de Funções de Derivação de Chaves (Java 25)
Essa JEP fornece uma API padrão (javax.crypto.KDF
) para derivar chaves criptográficas.
-
O que traz:
- Suporte oficial a KDFs (ex.: HKDF) direto no JDK.
- Uso unificado em vez de depender de bibliotecas externas ou implementações caseiras.
-
Impacto prático:
- Facilita cenários como TLS, HPKE e integrações com HSM/PKCS#11.
- Reduz código duplicado e riscos de segurança de soluções ad-hoc.
- O PBKDF2 continua disponível via
SecretKeyFactory
.
💻 Exemplos: Antes da JEP 510 | Depois da JEP 510
🗑️ Remoções e Depreciações
Parte da evolução do Java é também remover legados inseguros ou pouco usados, simplificando a base da JVM e incentivando o uso das APIs modernas.
JEP 471: Deprecar métodos de acesso à memória em sun.misc.Unsafe
para remoção (Java 23)
Essa JEP marca como deprecados para remoção 79 métodos de acesso à memória da classe interna sun.misc.Unsafe
.
- Motivo: preparar o ecossistema para migrar de uma API interna e frágil para alternativas oficiais e seguras.
-
Substitutos recomendados:
- VarHandle para acesso em memória on-heap.
- API de Funções e Memória (FFM) para acesso off-heap.
Impacto prático:
- Bibliotecas e frameworks que ainda usam
Unsafe
precisam migrar gradualmente para APIs suportadas. - A JVM introduz a opção
--sun-misc-unsafe-memory-access={allow|warn|debug|deny}
para ajudar a detectar esses usos em tempo de execução. - Em fases futuras, os métodos vão gerar avisos, exceções e, por fim, serão removidos.
*JEP 472: Preparação para Restringir o Uso de JNI * (Java 24)
Essa JEP começa a apertar o cerco ao uso do JNI (Java Native Interface).
- O que muda agora: a JVM passa a emitir avisos sempre que código carrega ou vincula bibliotecas nativas via JNI.
- Alinhamento: o comportamento de avisos segue o mesmo padrão já adotado pela API de Funções e Memória (FFM).
Impacto prático:
- Promove o conceito de “integridade por padrão”, incentivando devs a repensarem usos de JNI.
- Prepara o caminho para uma mudança maior: em versões futuras, o acesso nativo deve ser restringido por padrão, exigindo habilitação explícita na inicialização da JVM.
JEP 479: Remover a porta Windows 32-bit x86 (Java 24)
Essa JEP removeu do JDK todo o código e suporte de build para Windows 32-bit x86.
- Motivo: essa arquitetura está em desuso, e manter o suporte gerava complexidade extra na base de código e na infraestrutura de build/testes.
- Benefício: manutenção simplificada, menos código legado e foco em plataformas modernas (x64 e ARM).
Impacto prático:
- Quem ainda depende de Windows 32-bit precisa permanecer em versões antigas do JDK ou migrar para 64-bit.
- O time do OpenJDK concentra esforços em arquiteturas atuais, reduzindo risco de bugs em áreas pouco usadas.
JEP 486: Desativar Permanentemente o Security Manager (Java 24)
Essa JEP remove de vez a possibilidade de habilitar o Security Manager.
-
O que muda:
- A flag
-Djava.security.manager
na inicialização não tem mais efeito. - A chamada
System.setSecurityManager(...)
agora lançaUnsupportedOperationException
.
- A flag
-
Motivação:
- O recurso tinha baixo uso real.
- Custava caro manter e evoluir, já que criava restrições profundas dentro da JVM.
Impacto prático:
- Quem ainda tem dependências, flags de build ou parâmetros de runtime ligados ao Security Manager precisa remover ou atualizar essas referências.
- A API restante deve ser removida em futuras versões do JDK.
JEP 498: Aviso ao usar métodos de acesso à memória em sun.misc.Unsafe
(Java 24)
Essa JEP dá mais um passo na transição para longe do sun.misc.Unsafe
.
O que muda: na primeira chamada a métodos de acesso à memória em
Unsafe
, a JVM agora emite um aviso em tempo de execução.Opção de controle: a flag
--sun-misc-unsafe-memory-access={allow|warn|debug|deny}
define o comportamento (no JDK 24, o padrão é warn
).
Impacto prático:
- Facilita detectar usos de
Unsafe
durante a execução. - Prepara o ecossistema para a futura remoção definitiva desses métodos.
- Alternativas modernas já disponíveis:
- VarHandle para acesso on-heap.
- API de Funções e Memória (FFM) para acesso off-heap.
JEP 501: Deprecar a porta x86 32-bit para remoção (Java 24)
Essa JEP marca a porta x86 32-bit (ainda existente no Linux, já removida no Windows) como depreciada para remoção.
-
O que muda:
- Builds que tentarem habilitar essa porta exibem um aviso de depreciação.
- Só é possível prosseguir se usar a flag:
--enable-deprecated-ports=yes
-
Motivação:
- Reduzir o custo de manutenção.
- Focar os esforços em arquiteturas modernas (x64 e ARM).
Impacto prático:
- Projetos que ainda dependem de Linux 32-bit devem planejar a migração para 64-bit.
- A remoção definitiva está no horizonte, então esse é o último aviso antes da saída completa.
JEP 503: Remover a porta x86 32-bit (Java 25)
Essa JEP remove do JDK todo o código e suporte de build para a porta x86 32-bit.
- Contexto: no Java 24, a JEP 501 já havia marcado a porta como deprecada.
- Agora: a remoção é definitiva, não há mais suporte nem para builds experimentais.
Impacto prático:
- Simplificação da base de código e da infraestrutura de build/testes.
- Desbloqueio de recursos que não precisam mais manter fallback para 32-bit.
- Quem ainda depende de ambientes 32-bit precisa permanecer em versões antigas do JDK ou migrar para 64-bit.
🚀 Fechando o pacote: do Java 21 ao 25
O Java 25 marca a chegada de uma nova versão LTS, quase dois anos depois do Java 21. Nesse período, muita coisa mudou: o GC ficou mais eficiente, a JVM ganhou recursos para inicializar mais rápido, a linguagem ficou mais expressiva e a segurança já está preparada para desafios futuros.
👉 Por que atualizar é importante?
- Estabilidade: o Java 25 vai receber suporte até 2030, é nele que a comunidade e fornecedores vão concentrar seus esforços.
- Performance: várias melhorias trazem ganhos diretos sem precisar reescrever sua aplicação.
- Segurança: algoritmos modernos e pós-quânticos já fazem parte do JDK, reduzindo riscos.
- Manutenção: quanto antes você atualizar, menor o salto acumulado na próxima migração.
No fim, atualizar não é só “ficar na moda”: é garantir suporte, segurança e eficiência pro seu sistema.
Quer ver tudo isso funcionando na prática?
Montei um playground com exemplos antes e depois de cada JEP relevante, do Java 22 ao 25. É só clonar e brincar com os códigos.
Top comments (0)