O Java prossegue em sua evolução contínua com uma nova versão a cada seis meses e, dentro desta dinâmica, no último dia 22 de março de 2022 a Oracle disponibilizou o Java 18.
Neste artigo vamos entender as principais novidades do Java 18 e como você dev pode contribuir para a evolução dessa que é uma das linguagens de programação mais adotadas do mercado.
Conheça as novidades do Java 18
As principais novidades do Java 18 são:
- UTF-8 por Padrão (JEP 400)
- Servidor Web Simples (JEP 408)
- Trechos de Código na Documentação da API Java (JEP 413)
- Reimplementação do Núcleo de Reflexão com Method Handles (JEP 416)
- API Vector (JEP 417)
- Resolução de Endereço de Internet (JEP 418)
- API para Memória e Funções Externas (JEP 419)
- Correspondência de Padrões para switch (JEP 420)
- Descontinuação da Finalização para Remoção (JEP 421)
Alguns destes aprimoramentos do Java 18 ainda estão em incubação, ou seja, em caráter experimental para colher feedback de devs. Portanto, instale esta nova versão, teste e envie os seus comentários porque serão muito bem-vindos.
Caso deseje aprofundar-se em algum tópico, busque pela referência do respectivo identificador da Proposta de Melhoria para JDK (JEP) ou, no original, JDK Enhancement Proposal (JEP), ou utilize o link para a documentação original.
UTF-8 por Padrão (JEP 400)
A conversão entre os fluxos de dados e os valores de caracteres de 16-bit do Java é governada pelo conjunto de caracteres (charset). A partir do Java 18, o charset UTF-8 passa a ser o padrão de todas as APIs do Java.
Com isso, independentemente de sistemas operacionais, localidades e configurações, haverá um comportamento consistente entre as APIs do Java que dependem do conjunto de caracteres padrão.
Esta alteração não se aplica ao console porque este possui um charset padrão fixo, ou seja, não pode ser alterado. Portanto, a leitura e escrita no console continuará utilizando o charset retornado pelo método charset() da API java.io.Console.
Servidor Web Simples (JEP 408)
Que tal um servidor web para servir arquivos estáticos, testes simples e sem necessidade de configuração? Este novo recurso possui exatamente estas características! Talvez você responda que já utiliza um framework com este recurso embutido. Ok, entendo você, mas…
A principal motivação por trás deste novo recurso é proporcionar a estudantes e devs iniciantes em Java uma melhor experiência durante o aprendizado e, consequentemente, menor rejeição e maiores chances de adoção da linguagem.
A ideia é evitar a necessidade de instalação de outros softwares ou frameworks para o aprendizado do Java. Afinal, para quem está iniciando em programação, em uma nova linguagem ou até mesmo em um novo paradigma de programação, o aprendizado dos conceitos já nos fazem “queimar” muitos neurônios! =)
Fiz o teste deste novo recurso e, realmente, não precisa configurar nada! Vale a pena conferir.
Trechos de Código na Documentação da API Java (JEP 413)
Neste momento, talvez você pense: “Bem, isto já é possível com a tag @code!”
Sim, mas o trecho de código anotado com a tag @code é renderizado em um HTML sem validação! A nova tag @snippet é mais poderosa, dispõe de recursos mais avançados como realce de sintaxe, validação do código-fonte, separação do trecho de código em arquivo, comentários dentro do arquivo, dentre outros.
Além disso, a tag @snippet permite trechos de arquivos de configuração (ex.: .properties, .yaml) assim como de outras linguagens de programação.
Reimplementação do Núcleo de Reflexão com Method Handles (JEP 416)
O objetivo desta melhoria é reduzir o custo de manutenção e desenvolvimento das APIs java.lang.reflect e java.lang.invoke. Houve apenas uma mudança na implementação interna da API de reflexão (java.lang.reflection), não havendo alterações na utilização da mesma.
Mas atenção! Códigos dependentes de aspectos específicos e não documentados da implementação existente podem ser impactados. Este risco pode ser mitigado pelo parâmetro -Djdk.reflect.useDirectMethodHandle = false, que habilita a utilização da implementação antiga pela JVM, porém em uma versão futura tal parâmetro será desativado.
API Vector (JEP 417)
A API Vector (jdk.incubator.vector) está em sua terceira incubação, incorporando melhorias de performance e implementação em resposta aos feedbacks obtidos na segunda incubação no Java 17. Atenção para não confundir com a API Vector (java.util.vector), existente desde a versão 1.0 do Java, utilizada para implementar uma matriz de objetos expansível.
O objetivo desta nova API é possibilitar uma codificação multiplataforma fazendo uso do paralelismo de dados do hardware, habilitando devs com mais experiência expressarem algoritmos paralelos de dados complexos em Java para aplicações, por exemplo:
- Aprendizado de máquina (machine learning).
- Criptografia.
- Hash codes.
- Soluções dentro da própria JDK.
Estrategicamente é muito importante para o Java porque em conjunto com tipos de valores fazem do Java uma excelente plataforma para computação numérica, com processamento mais eficiente, rápido e seguro.
Resolução de Endereço de Internet (JEP 418)
A API java.net.InetAddress é responsável por resolver os nomes de domínios (host names) para endereços de protocolo de internet (IP address) e vice-versa, usando um resolvedor nativo do sistema operacional que, tipicamente, é configurado para usar uma combinação de um arquivo de domínios local e um sistema de nomes de domínio (DNS).
Este novo recurso define uma interface de provedor de serviço (SPI) para resolução de nomes de domínio e endereços, possibilitando que a API java.net.InetAddress utilize resolvedores que não sejam o da própria plataforma.
A seguir alguns exemplos de novas possibilidades deste novo recurso:
- integração de novos protocolos de resolução (ex.: DNS sobre TLS ou HTTPS).
- controle fino sobre os resultados de resolução por frameworks e aplicações.
- adaptação de bibliotecas existentes com um resolvedor customizado.
API para Memória e Funções Externas (JEP 419)
A API para Memória e Funções Externas (Foreing Function & Memory API – FFM API) está em sua segunda incubação, trazendo melhorias obtidas com os feedbacks da primeira incubação realizada no Java 17 sob o JEP 412.
O objetivo desta API é substituir a Interface Nativa do Java (JNI), permitindo programas em Java acessarem de forma segura memória externa (não gerenciada pela JVM) e funções externas (código fora da JVM), através da utilização de bibliotecas nativas e acesso à dados nativos, com um modelo desenvolvimento superior e puro do Java, performance igual ou melhor que a de outras APIs da JNI existentes, mais genérica e segura.
Correspondência de Padrões para switch (JEP 420)
A correspondência de padrões para switch (Pattern Matching for switch) é classificado como um recurso pré-estreado (preview feature). Um recurso pré-estreado consiste em um novo recurso da linguagem Java, da Máquina Virtual Java, ou da API Java SE com especificação completa, totalmente implementada, e ainda assim impermanente.
O objetivo da pré-estreia é provocar o feedback de devs com base em seu uso no mundo real. Estes feedbacks são decisivos para tornar ou não os recursos permanentes em uma futura versão do Java.
A correspondência de padrões para switch está em sua segunda pré-estreia. Originalmente foi proposta pelo JEP 406 e teve sua primeira pré-estreia no Java 17.
No Java 18 as seguintes melhorias estão sendo incorporadas na correspondência de padrões para switch:
- padrões no rótulo do case (pattern in switch labels);
- padrões guardados (guarded patterns) e padrões entre parêntesis (parenthesized patterns).
Vale a pena a leitura da documentação deste novo recurso porque traz muita legibilidade ao código. Seu switch nunca mais será o mesmo!!!
Descontinuação da Finalização para Remoção (JEP 421)
A finalização é um recurso disponível no Java desde a versão 1.0, com o objetivo de ajudar a evitar vazamentos de recursos (resource leaks). Um finalizador pode ser declarado em uma classe para liberar recursos subjacentes utilizados pela mesma.
class Export {
…
protected void finalize() {
// libera recursos subjacentes utilizados pela classe.
}
}
A coleta de lixo (garbage collection) agenda a finalização de um objeto inacessível para ser chamado antes de retomar a memória do objeto. Com isto, o método finalize() pode liberar os recursos.
Conceitualmente, funciona muito bem. Porém, este mecanismo possui falhas críticas fundamentais que podem ocasionar vulnerabilidades de segurança, problemas de performance, falhas de execução e dificuldades no modelo de programação. Por este motivo, decidiu-se pela descontinuação da finalização para remoção em uma versão futura.
A finalização continua ativa por padrão no Java 18, mas poderá ser desabilitada para testar os impactos na aplicação e avaliar as necessidades de ajustes na mesma. A opção de linha de comando –finalization=disabled fará com que a JVM iniciada não execute nenhum finalizador, inclusive aqueles declarados pela própria JDK.
Existem bibliotecas como Netty, Log4j, Guava e Apache Commons que utilizam finalizadores. Se sua aplicação faz uso de uma delas, então haverá impacto quando este recurso for desabilitado para testes.
Conclusão
Como visto ao longo do artigo, o Java 18 tem muitas novidades! Recomendo mergulhar nos JEPs acima, avaliar o impacto das mudanças e como poderá aplicar os novos recursos em seus projetos.
Gostou do artigo? Então, curta, comente e divida com sua rede profissional para multiplicar o conhecimento!
Até breve!