Classes ocultas, Classes seladas, blocos de texto , registros e EdDSA: o JDK 15 tem muito valor.
Como diz uma das minhas expressões favoritas, há muitos benefícios do chocolate em Java 15 . A nova versão (lançada em 15 de setembro de 2020) inclui 14 mudanças importantes (JEPs) destinadas a melhorar o JDK. Este artigo fornece uma visão geral rápida de novos produtos com base nas informações contidas no JEP.
Os 14 JEP podem ser divididos em cinco grupos. Para um estudo mais detalhado, consulte a documentação de cada um deles.
Nova funcionalidade que vai tirar o fôlego:
- JEP 339: Algoritmo de Assinatura Digital da Curva de Edwards (EdDSA)
- JEP 371: aulas ocultas
Adições à funcionalidade padrão Java SE existente:
- JEP 378: Blocos de Texto
- JEP 377: Coletor de lixo ZGC
- JEP 379: Shenandoah - Coletor de lixo de baixa pausa
Melhorias na funcionalidade legada do Java SE:
- JEP 373: Revisão da obsoleta API DatagramSocket
Estamos ansiosos para novos produtos:
- JEP 360: Classes seladas (visualização)
- JEP 375: Correspondência de padrões para instanceof (segunda visualização)
- JEP 384: Inscrições (segundo rascunho)
- JEP 383: API de acesso à memória externa (função de segunda incubadora)
Remoção e rescisão do suporte:
- JEP 372: Nashorn JavaScript Engine
- JEP 374:
- JEP 381: Solaris SPARC
- JEP 385: RMI
,
Algoritmo de assinatura digital da curva de Edwards ( JEP 339 ). Serei o primeiro a admitir que o Edwards-Curve Digital Signature Algorithm (EdDSA) está um pouco além do meu conhecimento de criptografia. Ok, eu não sei nada sobre isso. No entanto, este JEP foi projetado como uma implementação independente de plataforma de EdDSA com melhor desempenho do que a implementação C existente, ECDSA.
De acordo com a documentação do JDK, EdDSA é um esquema de assinatura de curva elíptica moderno que tem várias vantagens sobre os existentes no JDK.
Metas de implementação:
- O principal objetivo deste JEP é implementar o esquema de assinatura conforme padronizado no RFC 8032 . No entanto, o novo esquema não substitui o ECDSA.
- - EdDSA , ECDSA . , EdDSA, Curve25519 ~126 , , ECDSA, secp256r1 ~128 .
- , . .
Agora você sabe mais do que eu. Fique ligado em um artigo da Java Magazine explicando a EdDSA em breve.
Classes ocultas ( JEP 371 ) são classes que não podem ser chamadas diretamente pelo bytecode de outras classes. Eles devem ser usados por estruturas que criam classes dinamicamente em tempo de execução e as usam indiretamente por meio de um mecanismo de reflexão. As classes geradas dinamicamente podem ser necessárias apenas por um período limitado de tempo, portanto, mantê-las durante o tempo de vida de uma classe gerada estaticamente pode aumentar desnecessariamente o consumo de memória.
As classes geradas dinamicamente também são indetectáveis. Encontrar essas classes pelo nome seria prejudicial, pois prejudica seu propósito, que é o de serem apenas um detalhe de implementação de uma classe gerada estaticamente.
O lançamento das classes ocultas estabelece a base para os desenvolvedores pararem de usar a API não padrão sun.misc.Unsafe :: defineAnonymousClass . A Oracle pretende remover e remover essa classe no futuro.
Adições aos padrões Java SE existentes
Os blocos de texto ( JEP 378 ) que vieram do Projeto Amber foram finalmente lançados após duas versões preliminares no JDK 13 e 14. O objetivo de sua criação foi o desejo dos desenvolvedores de reduzir a dificuldade de declarar e usar literais de string multilinhas em Java.
Os blocos de texto formatam strings automaticamente de uma forma previsível, mas se isso não for suficiente, o desenvolvedor pode assumir a formatação. A segunda versão da funcionalidade preliminar apresenta duas novas sequências de escape para lidar com novas linhas e espaços. Por exemplo, \ <line-terminator> suprime explicitamente a inserção de um caractere de nova linha.
Anteriormente, para imprimir uma longa linha de texto, você teria que escrever assim:

Usar \ torna o código mais fácil de ler:

A seqüência de escape do \ s pode impedir que espaços finais sejam removidos. Assim, o texto a seguir representa três linhas, cada uma das quais composta por exatamente cinco caracteres (na linha do meio, correspondente ao verde, \ s não é utilizado, pois já contém cinco caracteres).

O coletor de lixo ZGC ( JEP 377 ) foi introduzido no JDK 11 como um recurso experimental. Agora recebeu status oficial. O ZGC é um coletor de lixo escalonável e habilitado para NUMA, com baixa latência de coleta de lixo (menos de 10 milissegundos, mesmo em heaps de vários terabytes). O tempo médio de pausa, conforme testado pela Oracle, é inferior a 1 milissegundo e o máximo é inferior a 2 milissegundos. A Figura 1 compara o coletor de lixo paralelo Java, G1 e ZGC, com o tempo de pausa do ZGC aumentado por um fator de 10.

Figura 1. Comparação dos tempos de pausa do coletor de lixo
No entanto, para muitas cargas de trabalho, G1 (que ainda é o padrão) pode ser um pouco mais rápido do que ZGC. Além disso, para heaps muito pequenos, como aqueles que têm apenas algumas centenas de megabytes, o G1 também pode ser mais rápido. Portanto, é recomendável executar seus próprios testes com suas próprias cargas para ver qual coletor de lixo usar.
Importante: como o ZGC não é mais experimental (incluído na compilação do Oracle OpenJDK e no Oracle JDK), você não precisa mais usar -XX: + UnlockExperimentalVMOptions para ativá-lo.
Shenandoah ( JEP 379) É outra variante do coletor de lixo disponível em algumas compilações do OpenJDK. Tem sido experimental desde o JDK 12. Agora, como no ZGC, XX: + UnlockExperimentalVMOptions não é necessário.
Modernização da funcionalidade legada do Java SE
Retrabalhando a API DatagramSocket obsoleta ( JEP 373 ). Considere isso basicamente uma refatoração de algum código jurássico, já que este JEP substitui as implementações antigas e difíceis de manter das APIs java.net.DatagramSocket e java.net.MulticastSocket por implementações mais simples e modernas que são fáceis de manter e depurar, e que irão trabalhar com fluxos virtuais do Project Loom.
Como há muitos códigos que usam a API antiga (desde o JDK 1.0), a implementação obsoleta não será removida. Na verdade, uma nova propriedade de sistema específica do JDK, jdk.net.usePlainDatagramSocketImpl, configura o JDK para usar uma implementação obsoleta se a refatoração da API causar problemas em testes de regressão ou em alguns casos.
Estamos ansiosos para novos produtos
Classes seladas ( JEP 360 ). A primeira versão de pré-produção criada no Projeto Amber. As classes e interfaces seladas restringem sua extensão ou implementação a outras classes. Por que isso é importante? Um desenvolvedor pode desejar gerenciar o código responsável pela implementação de uma classe ou interface específica. As classes seladas fornecem uma maneira mais declarativa do que os modificadores de acesso para restringir o uso da superclasse. Por exemplo:

O objetivo de lacrar uma classe é permitir que o código do cliente saiba quais subclasses são permitidas. Afinal, pode haver casos de uso em que se espera que a definição original de uma classe (ou interface) seja completamente exaustiva e em que o desenvolvedor não permita que ela seja estendida fora do controle - apenas classes explicitamente especificadas podem.
Existem algumas restrições para classes seladas:
- A classe selada e suas subclasses permitidas devem estar no mesmo módulo. Se eles forem declarados em um módulo sem nome, eles devem ser colocados no mesmo pacote
- Cada subclasse permitida deve estender diretamente a classe selada
- , , , — final, sealed nonsealed ( )
Correspondência de padrões por exemplo ( JEP 375 ). A segunda prévia é outro desenvolvimento do Projeto Amber. A primeira versão preliminar da funcionalidade estava em Java 14 e não há mudanças em comparação a ela.
O objetivo é melhorar o Java por meio da correspondência de padrões para o operador instanceof. Isso permite que você expresse de forma mais concisa e segura a lógica geral do programa, ou seja, a extração condicional de componentes de objetos. Deixe-me referir-lhe o excelente artigo de Mal Gupta " Correspondência de padrões por exemplo em Java 14 " como um exemplo.
Inscrições ( JEP 384), segundo rascunho. Registros são classes que agem como portadores transparentes de dados imutáveis. O novo JEP inclui esclarecimentos com base no feedback da comunidade e oferece suporte a várias novas formas adicionais de classes e interfaces locais. As inscrições também vêm do Projeto Amber.
Os registros são uma construção orientada a objetos que expressa uma agregação simples de valores. Assim, eles ajudam os programadores a se concentrarem na modelagem de dados imutáveis em vez de comportamento extensível. Os registros implementam automaticamente métodos baseados em dados, como iguais e acessadores. As entradas também preservam princípios Java de longa data, como tipagem nominal e compatibilidade de migração. Em outras palavras, eles facilitam a codificação e a leitura de classes que contêm dados imutáveis.
O Acesso à memória externa ( JEP 383 ) é a segunda versão incubadora da API que permite que os programas Java acessem com segurança e eficiência a memória externa fora do heap Java. O objetivo é começar a substituir java.nio.ByteBuffer e sun.misc.Unsafe. Faz parte do projeto Panama que melhora a comunicação entre Java e outras APIs.
O JEP descreve adequadamente a necessidade dessa inovação da seguinte maneira:
Quando se trata de acessar memória externa, os desenvolvedores enfrentam um dilema - devem escolher um caminho seguro, mas limitado (e possivelmente menos eficiente), como a API ByteBuffer, ou devem desistir das garantias de segurança e adotar uma API insegura perigosa e sem suporte?
Este JEP apresenta uma API segura, sustentável e eficiente para acessar a memória externa. Ao fornecer uma solução direcionada para o problema de acesso à memória externa, os desenvolvedores ficarão livres das limitações e perigos das APIs existentes. Eles também obterão um melhor desempenho, pois a nova API foi projetada do zero com otimizações JIT em mente.
Remoção e fim do suporte
Nenhuma dessas decisões deve ser controversa.
Remoção do mecanismo Nashorn JavaScript ( JEP 372 ). Este motor, sua API e ferramenta jjs foram descontinuados no Java 11. É hora de dizer adeus.
Desativar e eliminar o bloqueio reservado ( JEP 374 ) remove a técnica de otimização antiga usada no HotSpot JVM para reduzir a sobrecarga associada ao bloqueio não verificado. Esse bloqueio tem resultado historicamente em melhorias significativas de desempenho em relação aos métodos de bloqueio convencionais, mas os ganhos de desempenho vistos no passado são muito menos óbvios hoje. O custo de execução de instruções atômicas em processadores modernos caiu.
O bloqueio redundante resultou em muitos códigos complexos e essa complexidade impede que a equipe de desenvolvimento Java faça alterações significativas no mecanismo de sincronização. Desativando o bloqueio e deixando para o programador reativá-lo, a equipe de desenvolvimento Java espera determinar se seria sensato removê-lo inteiramente em uma versão futura.
Removendo portas Solaris e SPARC ( JEP 381 ). Nesse caso, todo o código-fonte específico do sistema operacional Solaris e da arquitetura SPARC é removido. Não há mais nada a dizer.
Exclua a ativação do RMI para desinstalação posterior ( JEP 385) Simplifica o Java removendo a parte obsoleta da chamada de métodos remotos que era opcional no Java 8.
O uso da ativação RMI é cada vez mais reduzido. A equipe Java não vê nenhuma evidência de que novos aplicativos foram escritos usando-o, e há evidências de que muito poucos aplicativos existentes usam a ativação RMI. A pesquisa em várias bases de código de código aberto não encontrou quase nenhuma menção a quaisquer APIs associadas a ela. Não há relatórios de erros de ativação de RMI gerados externamente há vários anos.
O suporte à ativação de RMI como parte da plataforma Java tem um custo de manutenção contínuo. Isso adiciona complexidade ao RMI. Você pode remover a ativação do RMI sem afetar o resto do RMI. Removê-lo não reduz o valor do desenvolvedor Java, mas reduz os custos de manutenção de longo prazo do JDK.
Conclusão
Java 15 continua seu ciclo de lançamento de seis meses e é um lançamento de tamanho médio útil para a maioria dos desenvolvedores.