Com regularidade semelhante à de um relógio atômico, a versão mais recente do Java, JDK 22, foi lançada na semana passada. Embora esta não seja uma versão de suporte de longo prazo (LTS), não há nada que impeça você de usá-la em produção e ela contém alguns novos recursos interessantes.
Vamos mergulhar e ver o que isso nos traz.
Novos recursos para a plataforma Java são definidos por meio de JDK Enhancement Proposals (JEPs), e o JDK 22 contém 12 deles. Coincidentemente, nos últimos 13 lançamentos Java, desde a mudança para uma cadência de seis meses, o número médio de JEPs (até o número inteiro mais próximo) também é 12. Você poderia, portanto, descrever isso como um lançamento médio!
Dividindo isso ainda mais, temos quatro recursos finais e oito recursos de visualização ou módulos de incubadora.
Mudanças na linguagem Java
PEC 447: Declarações antes super()
(visualização). Como uma linguagem orientada a objetos, Java oferece a capacidade de estender outra classe (não final) e herdar estado e comportamento (quando permitido). Para que isso funcione de maneira confiável, os construtores das classes devem ser chamados de cima para baixo para evitar que os construtores da subclasse interfiram nos construtores da superclasse. Quando um desenvolvedor decide fazer uma chamada explícita ao construtor da superclasse, esta deve ser a primeira instrução.
Isto impõe algumas limitações, que podem levar a um código mais complexo do que o desejado. A mais óbvia delas é a incapacidade de realizar um teste nos parâmetros do construtor antes de chamar o construtor da superclasse. Se um teste resultar no lançamento de uma exceção, a chamada ao construtor da superclasse se tornará uma sobrecarga tecnicamente desnecessária.
JEP 447 introduz uma maneira controlada de permitir declarações antes de uma chamada para super()
. Qualquer referência ao this
ou super
referências de objetos gerarão erros, pois o objeto referenciado não teria sido totalmente inicializado. Existem diversas outras restrições descritas detalhadamente neste PEC.
PEC 456: Padrões e variáveis sem nome. Introduzido como um recurso de visualização no JDK 21, agora é final sem quaisquer alterações.
Este recurso permite que os desenvolvedores usem um único sublinhado _
para representar uma variável que não será usada. Em vez de nomear variáveis que desorganizam nosso código e dificultam a visualização do que está acontecendo, podemos manter a sintaxe correta para uma construção e ajudar na legibilidade.
Um exemplo simples é um foreach
loop de estilo que itera sobre uma coleção, mas não usa o valor recuperado:
for (String name : userList) userCount++;
Isso pode ser simplificado para:
for (String _ : userList) userCount++;
Este é um exemplo bastante trivial, mas quando aplicado a padrões, seu valor fica mais claro. Usando padrões de registro compostos, que são uma forma de padrão de desconstrução, poderíamos ter algo assim:
public void printTopLeftX(Rectangle r) { if (r instanceof ColourRectangle(ColourPoint( Point(double x, double y), Colour c), ColourPoint bottomRight)) System.out.println(x); }
Como tudo o que usamos é o valor de x, todas as outras variáveis (incluindo sua definição de tipo) são supérfluas e tornam o código muito denso. Usando padrões sem nome, podemos reescrever isso como:
public void printTopLeftX(Rectangle r) { if (r instanceof ColourRectangle(ColourPoint(Point(var x, _), _), _) ) System.out.println(x); }
Eles também podem ser usados na correspondência de padrões para expressões switch e lambda.
PEC 459: Modelos de string (visualização). Introduzido como um recurso de visualização no JDK 21, ainda está em versão prévia, sem alterações visíveis ao desenvolvedor.
A construção de strings em Java pode ser realizada de várias maneiras diferentes: através da concatenação de strings e do uso de classes de biblioteca como StringBuilder
e String.format()
. Os modelos de string fornecem uma maneira simplificada de expressar strings que contêm valores calculados em tempo de execução.
Agora temos um processador de modelo de string, STR
que pode realizar interpolação de strings.
Como exemplo simples, podemos inserir valores:
String name = "Simon"; String info = STR." My name is {name}";
O verdadeiro poder dos templates de string é que você pode fazer interpolações muito mais sofisticadas, por exemplo, usando chamadas de método:
String s = STR." We are here { // Method call DateTimeFormatter .ofPattern("B") .format(LocalTime.now()) } learning Java";
Observe que podemos recuar o código como quisermos sem afetar a string gerada e até incluir comentários.
PEC 463: Classes e instâncias declaradas implicitamente main
métodos (visualização). Isso foi introduzido como um recurso de visualização no JDK 21 e continua assim com algumas mudanças significativas.
Escrever até mesmo o aplicativo Java mais simples requer muita cerimônia (ou código padrão). Para o habitual “olá mundo”, precisamos de tudo isso:
public class Hello { public static void main(String() args) { System.out.println(“Hello, World!”); } }
JEP 463 permite que um programa use uma instância main
método, que não precisa ser marcado como static
ou public
. Ele também fornece uma unidade de compilação de forma que não precisamos mais definir explicitamente a classe. O efeito geral dessas mudanças é reduzir nossa aplicação a:
void main(){ System.out.printIn("Hello, World!"); }
Isso será de uso limitado para desenvolvedores experientes, mas ajudará aqueles que estão começando a usar Java.
Mudanças na biblioteca
PEC 454: Função externa e API de memória. Introduzido inicialmente como um recurso de visualização no JDK 19, agora é um recurso final.
Esta API faz parte do Projeto Panamá e fornece uma substituição mais simples para a Java Native Interface (JNI). Essas APIs fornecem maneiras padrão de interagir com memória nativa e bibliotecas externas, que são compiladas diretamente em código nativo em vez de bytecodes. A interação bidirecional é possível por meio de chamadas descendentes (de Java para funções nativas) e chamadas ascendentes (retornos de chamada de código nativo para código Java).
Uma ferramenta adicional, jextract
, pode ser usado para gerar código para acessar uma biblioteca externa. Isso não está incluído por padrão no JDK, mas está disponível como código-fonte no OpenJDK.
PEC 457: API de arquivo de classe (visualização). Para a maioria dos desenvolvedores, esta não será uma API interessante. Processar arquivos de classe é algo que a JVM obviamente deve fazer (para carregar e executar aplicativos) e também é algo exigido por muitos frameworks e bibliotecas.
O objetivo desta API é padronizar e simplificar a forma como os usuários podem interagir com arquivos de classe.
PEC 460: API de vetor (visualização). Esta API detém o recorde de recurso de visualização mais longo, estando em sua sétima iteração no JDK 22.
Os vetores, neste caso, referem-se a registros muito amplos disponíveis em todas as CPUs modernas. Usando uma técnica chamada instrução única, dados múltiplos (SIMD), vários elementos de uma matriz podem ser carregados no vetor e a mesma operação (como adicionar ou subtrair um valor) pode ser executada em um único ciclo de clock. Este processamento paralelo pode levar a melhorias significativas de desempenho para operações numericamente intensivas.
A API fornece maneiras para o desenvolvedor especificar como os valores devem ser armazenados nos vetores e as operações necessárias neles.
Para situações simples, o compilador just-in-time (JIT) interno da JVM reconhecerá onde as operações vetoriais podem ser usadas e as aplicará automaticamente. Para situações mais complexas, por exemplo, onde um loop inclui um teste condicional para um cálculo, esta API será útil.
Alternativamente, a JVM Azul Platform Prime Zing usa um compilador JIT substituto chamado Falcon. Com base no projeto LLVM de código aberto, ele pode reconhecer muito mais situações em que operações vetoriais podem ser usadas e oferecer melhor desempenho sem modificações de código.
PEC 461: Coletores de fluxo (visualização). A API de streams foi introduzida no JDK 8 e, combinada com expressões lambda, forneceu um estilo de programação mais funcional que não era possível em Java antes.
Os fluxos consistem em uma fonte que fornece elementos que podem passar por zero ou mais operações intermediárias antes que um resultado ou efeito colateral seja gerado usando uma operação de terminal.
Para a operação do terminal é possível definir sua própria funcionalidade através Stream::collector
. Embora exista um rico conjunto de operações intermediárias, elas são fixas e não podem ser estendidas por um desenvolvedor.
A API Stream Gatherer agora fornece uma maneira de definir uma nova operação intermediária.
Um coletor é definido por quatro funções: um inicializador opcional, um integrador, um combinador opcional e um finalizador opcional. Usando-os, os desenvolvedores têm total flexibilidade sobre como os elementos de entrada do coletor são processados e a saída gerada é passada para a próxima operação intermediária ou terminal.
PEC 462: Simultaneidade estruturada (visualização). Isso foi introduzido pela primeira vez no JDK 19 como um módulo de incubadora e tem sido um recurso de visualização desde o JDK 21. Nenhuma alteração foi feita nesta versão.
Por sua própria natureza, escrever código multithread confiável é um desafio. Ao longo da história do Java, tivemos muitos novos recursos destinados a tornar essa tarefa pelo menos um pouco mais simples. Os utilitários de simultaneidade, a estrutura fork-join e os fluxos paralelos forneceram soluções para diferentes tipos de situações de multithreading.
A simultaneidade estruturada, parte do Projeto Loom, trata múltiplas tarefas executadas em diferentes threads como uma única unidade de trabalho. Isso torna o tratamento de erros e o cancelamento mais simples de lidar.
PEC 464: Valores com escopo definido (visualização). Isso foi introduzido como um recurso de visualização no JDK 21 e continua no JDK 22 sem alterações.
Os valores com escopo também estão relacionados ao Project Loom e fornecem uma alternativa para variáveis locais de thread. A diferença crítica é que, como valor e não como variável, eles são imutáveis.
Variáveis locais de thread têm mais complexidade do que normalmente é necessário e têm um custo substancial de recursos associado a elas. Com threads virtuais permitindo ordens de escalabilidade maiores do que threads de plataforma, esse custo de recursos pode se tornar um fator limitante. Os valores com escopo resolvido resolvem esse problema de uma forma que permite aos desenvolvedores a flexibilidade necessária para lógica de aplicativo multithread.
JVM e outras mudanças
PEC 423: Fixação de região para G1. Esta é uma melhoria na forma como o coletor de lixo (GC) G1 funciona que reduz a latência ao usar JNI.
Ao contrário do código Java, as interações JNI podem usar ponteiros explícitos para objetos no heap. A realocação desses objetos dentro do heap não é possível quando um thread Java está executando uma região crítica do código JNI. Para evitar esse problema, o G1 desativa o GC durante regiões críticas, o que pode levar ao aumento da latência, pois outros threads não JNI serão bloqueados se acionarem um GC.
Essa mudança permite que o G1 GC seja executado mesmo quando um thread está em uma região crítica, fixando regiões de memória usadas pelo código JNI, mas permitindo que outras sejam realocadas e coletadas.
PEC 458: inicia programas de código-fonte com vários arquivos. No JDK 11, o JEP 330 introduziu a capacidade de executar um único arquivo de origem sem a necessidade de compilá-lo diretamente. Isso está relacionado à simplificação da introdução ao Java, conforme discutido no JEP 463 acima.
JEP 458 aprimora o java
inicializador de aplicativos, permitindo que ele execute um programa fornecido como vários arquivos de código-fonte Java, em vez de apenas um. A maioria dos desenvolvedores usa um IDE para desenvolvimento de projetos e jshell
para experimentação de trechos de código.
Este recurso será muito útil para aqueles que estão apenas começando sua jornada de aprendizado de programação em Java.
Acima da média
Como você pode ver, o JDK 22 contém um número médio de novos recursos, mas é melhor que a média no que esses recursos oferecem. A Azul oferece downloads gratuitos de nossas versões Zulu do OpenJDK Community Edition que você pode instalar e experimentar. Por que não tentar?
Simon Ritter é vice-CTO e campeão Java da Azul.
–
O New Tech Forum oferece um local para líderes de tecnologia – incluindo fornecedores e outros colaboradores externos – explorarem e discutirem tecnologias empresariais emergentes com profundidade e amplitude sem precedentes. A seleção é subjetiva, baseada na escolha das tecnologias que acreditamos serem importantes e de maior interesse para os leitores do InfoWorld. A InfoWorld não aceita material de marketing para publicação e reserva-se o direito de editar todo o conteúdo contribuído. Envie todos consultas para [email protected].