Recursos do Java 10

Java 10 é o lançamento mais rápido de uma versão do Java em seus 23 anos de história. O Java tem sido criticado por seu crescimento e evolução lentos, mas o Java 10 simplesmente quebrou esse conceito. O Java 10 é um lançamento com muitas mudanças futuristas, cujo alcance e impacto podem não ser óbvios, mas são de grande alcance. Neste artigo, discutiremos as várias características adicionadas no lançamento do Java 10. Antes disso, vamos revisar algumas mudanças introduzidas no modelo de lançamento do Java.

Modelo de Suporte de Longo Prazo

A partir de 2017, a Oracle e a comunidade Java anunciaram a mudança para uma nova cadência de 6 meses para o Java. Mudou para um modelo de Suporte de Longo Prazo (LTS) para os produtos Oracle Java SE. O que isso significa? A versão LTS dos produtos oferecerá suporte premium e sustentado pela Oracle e será direcionada a cada 3 anos. Cada lançamento do Java é modelado após uma ou duas principais características, e essas características impulsionam o lançamento. Qualquer obstáculo adia o lançamento e atrasa no mercado. O Projeto Jigsaw foi uma característica importante do Java 9, adiando as datas de lançamento algumas vezes e o lançamento foi atrasado por mais de 1,5 anos. O lançamento a cada 6 meses seguirá um trem de lançamento. O trem de lançamento terá um cronograma a cada 6 meses. As características que são selecionadas são incluídas no trem; caso contrário, esperam pelo próximo trem programado.

Oracle JDK vs OpenJDK

Para ser mais amigável aos desenvolvedores, a Oracle e a comunidade Java agora promovem os binários do OpenJDK como o JDK primário daqui para frente. Isso é um grande alívio em relação aos dias anteriores, onde os binários do JDK eram proprietários e licenciados pela Oracle, que tinham várias restrições em torno da redistribuição. No entanto, a Oracle continuará produzindo seu JDK, mas apenas para lançamentos de suporte de longo prazo. Isso é um passo em direção a ser mais amigável à nuvem e aos contêineres, já que os binários do OpenJDK podem ser distribuídos como parte de um contêiner. O que isso significa? Os binários do OpenJDK serão lançados a cada 6 meses, enquanto os binários do Oracle JDK serão lançados a cada 3 anos (versão LTS). Quais binários do JDK serão adotados? Grandes organizações levam tempo para migrar entre as versões; elas se agarram à versão até poderem. A adoção da indústria para o Java 6 foi maior do que para o Java 7 e, em seguida, a indústria está gradualmente migrando para o Java 8. Na minha opinião, as versões LTS serão as mais favorecidas pelas empresas. No entanto, se será a versão LTS do Oracle JDK ou do OpenJDK ainda é desconhecido, em parte porque há muito acontecendo no espaço da nuvem. O Java 9 e 10 são lançamentos não-LTS. O Java 11, que está previsto para setembro de 2018, será um lançamento LTS.

Recursos do Java 10

Vamos dar uma olhada nas funcionalidades disponíveis no Java 10.

  1. Versionamento Baseado em Tempo (JEP 322)

Com a adoção do ciclo de lançamento baseado em tempo, a Oracle alterou o esquema de string de versão da Plataforma Java SE e do JDK, juntamente com as informações de versionamento relacionadas, para os modelos de lançamento baseados em tempo presentes e futuros. O novo padrão do número de versão é: $FEATURE.$INTERIM.$UPDATE.$PATCH $FEATURE: o contador será incrementado a cada 6 meses e será baseado em versões de lançamento de recursos, por exemplo: JDK 10, JDK 11. $INTERIM: o contador será incrementado para lançamentos não relacionados a recursos que contenham correções de bugs e melhorias compatíveis, mas sem alterações incompatíveis. Geralmente, isso será zero, pois não haverá lançamento intermediário em um período de seis meses. Isso é mantido para uma revisão futura do modelo de lançamento. $UPDATE: o contador será incrementado para lançamentos de atualização compatíveis que corrigem problemas de segurança, regressões e bugs em novos recursos. Isso é atualizado um mês após o lançamento do recurso e a cada 3 meses a partir de então. O lançamento de abril de 2018 é JDK 10.0.1, o lançamento de julho é JDK 10.0.2 e assim por diante. $PATCH: o contador será incrementado para um lançamento de emergência para corrigir um problema crítico. Novas APIs foram adicionadas para obter esses valores de contador programaticamente. Vamos dar uma olhada;

Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();

Agora, vamos dar uma olhada no iniciador Java que retorna as informações de versão:

$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

O formato do número da versão é “10”, já que não há outro contador que não seja zero. A data de lançamento é adicionada. 18.3 pode ser lido como o ano de 2018 e o 3º mês, compilação 10+46 é a 46ª compilação para a versão 10. Para uma compilação hipotética 93 do JDK 10.0.1, a compilação será 10.0.1+939. ### Inferência de Tipo de Variável Local (JEP 286)

O Tipo de Inferência de Variável Local é a maior nova funcionalidade no Java 10 para desenvolvedores. Ele adiciona inferência de tipo às declarações de variáveis locais com inicializadores. A inferência de tipo local pode ser usada apenas nos seguintes cenários:

  • Limitado apenas à Variável Local com inicializador
  • Índices do loop for aprimorado ou índices
  • Local declarado no loop for

Vamos dar uma olhada em seu uso:

var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList
// Índice do Loop For Aprimorado
for (var number : numbers) {
	System.out.println(number);
}
// Variável local declarada em um loop
for (var i = 0; i < numbers.size(); i++) {
	System.out.println(numbers.get(i));
}

Você pode ler mais sobre isso em nosso post exclusivo sobre inferência de tipo de variável local Java 10.

Esta funcionalidade permite que o compilador JIT baseado em Java, Graal, seja utilizado como um compilador JIT experimental na plataforma Linux/x64. Esta é, de longe, a inclusão mais futurista na lista de recursos do Java 10. Graal foi introduzido no Java 9. É uma alternativa ao compilador JIT ao qual estávamos acostumados. É um plugin para a JVM, o que significa que o compilador JIT não está vinculado à JVM e pode ser dinamicamente conectado e substituído por qualquer outro plugin que esteja em conformidade com o JVMCI (Interface de Compilador JVM de Nível Java). Ele também traz a compilação Ahead of Time (AOT) para o mundo Java. Também suporta a interpretação de linguagens poliglotas. “Um compilador Just in Time baseado em Java escrito em Java para converter o bytecode Java em código de máquina.” Isso é confuso? Se a JVM é escrita em Java, então você não precisa de uma JVM para executar a JVM? A JVM pode ser compilada AOT e, em seguida, o compilador JIT pode ser utilizado dentro da JVM para melhorar o desempenho por meio da otimização de código ao vivo. Graal é uma reescrita completa do compilador JIT em Java, do zero. O compilador JIT anterior foi escrito em c++. É considerado um dos estágios finais de evolução para qualquer linguagem de programação. Você pode alternar para Graal com os seguintes parâmetros JVM:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Você pode aprender mais sobre Graal a partir da apresentação de Chris Seaton.

Esta funcionalidade ajuda a melhorar a pegada inicial, estende a funcionalidade existente de Compartilhamento de Dados de Classe (“CDS”) para permitir que as classes da aplicação sejam colocadas no arquivo compartilhado. A JVM, ao iniciar, realiza algumas etapas preliminares, uma das quais é carregar as classes na memória. Se houver vários JARs com várias classes, o atraso na primeira solicitação é claramente visível. Isso se torna um problema com arquitetura serverless, onde o tempo de inicialização é crítico. Para reduzir o tempo de inicialização da aplicação, o compartilhamento de dados de classe da aplicação pode ser usado. A ideia é reduzir a pegada compartilhando metadados de classe comuns entre diferentes processos Java. Isso pode ser alcançado pelos seguintes 3 passos: Determinar as classes a serem arquivadas: Use o iniciador Java para criar uma lista de arquivos a serem arquivados, isso pode ser alcançado pelos seguintes parâmetros:

$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld

Criar o arquivo AppCDS: Use o iniciador Java para criar o arquivo do conjunto de arquivos a ser usado para o CDS da aplicação, isso pode ser alcançado pelos seguintes parâmetros:

$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar

Usar o arquivo AppCDS: Use o iniciador Java com os seguintes parâmetros para usar o CDS da aplicação.

$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
  1. Coleta Paralela Completa para G1 (JEP 307)

O coletor de lixo G1 tornou-se padrão no JDK 9. O coletor de lixo G1 evita qualquer coleta de lixo completa, mas quando as threads concorrentes para coleta não conseguem reviver a memória rápido o suficiente, a experiência do usuário é afetada. Essa mudança melhora a latência máxima do G1, tornando o GC completo paralelo. O algoritmo de marcação-limpeza-compactação do coletor G1 é paralelizado como parte dessa mudança e será acionado quando as threads concorrentes para coleta não conseguirem reviver a memória rápido o suficiente. 25. ### Interface do Coletor de Lixo (JEP 304)

Esta JEP é uma mudança futurista. Melhora o isolamento de código dos diferentes coletores de lixo, introduzindo uma Interface Comum de Coletor de Lixo. Essa mudança proporciona melhor modularidade ao Código Interno do GC. Isso ajudará no futuro para adicionar novos GC sem alterar a base de código existente, também ajudará na remoção ou limpeza dos GCs anteriores. 26. ### Extensões Adicionais de Tags de Idioma Unicode (JEP 314)

Essa funcionalidade melhora java.util.Locale e APIs relacionadas para implementar extensões de tags de idioma BCP 47 adicionais do Unicode. A partir do Java SE 9, as extensões de tags de idioma BCP 47 U suportadas são “ca” e “nu”. Essa JEP adicionará suporte para as seguintes extensões adicionais:

  • cu (tipo de moeda)
  • fw (primeiro dia da semana)
  • rg (substituição de região)
  • tz (fuso horário)

Para apoiar estas extensões adicionais, foram feitas alterações em várias APIs para fornecer informações baseadas em U ou extensões adicionais.

java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider
  1. Certificados Raiz (JEP 319)

Com o intuito de promover o OpenJDK e torná-lo mais atrativo para os usuários da comunidade, esta funcionalidade fornece um conjunto padrão de certificados de Autoridade de Certificação (CA) raiz no JDK. Isso também significa que os binários da Oracle e do Open JDK serão funcionalmente os mesmos. Componentes críticos de segurança como TLS funcionarão por padrão nas compilações do OpenJDK no futuro.30. ### Handshakes Thread-Local (JEP 312)

Esta é uma funcionalidade interna da JVM para melhorar o desempenho. Uma operação de handshake é um retorno de chamada que é executado para cada JavaThread enquanto essa thread está em um estado de safepoint. A chamada de retorno é executada pelo próprio thread ou pelo thread VM mantendo o thread em um estado bloqueado. Esta funcionalidade fornece uma maneira de executar um retorno de chamada em threads sem realizar um safepoint global da VM. Torna possível e barato parar threads individuais e não apenas todas ou nenhuma.31. ### Alocação de Heap em Dispositivos de Memória Alternativos (JEP 316)

As aplicações tornaram-se exigentes em memória, com um aumento nas aplicações nativas de nuvem, em bancos de dados em memória e em aplicações de streaming. Para atender a esses serviços, existem várias arquiteturas de memória disponíveis. Essa funcionalidade aprimora a capacidade do HotSpot VM de alocar o heap de objetos Java em um dispositivo de memória alternativo, como um NV-DIMM, especificado pelo usuário. Este JEP visa dispositivos de memória alternativos que possuem as mesmas semânticas que a DRAM, incluindo as semânticas de operações atômicas, e podem, portanto, ser usados em vez da DRAM para o heap de objetos sem nenhuma alteração no código da aplicação existente.

Esta é uma mudança de organização para remover a ferramenta javah do JDK. A funcionalidade da ferramenta foi adicionada ao javac como parte do JDK 8, proporcionando a capacidade de escrever arquivos de cabeçalho nativos durante o tempo de compilação, tornando o javah desnecessário.

Ao longo dos anos, houve vários repositórios Mercurial para o código-fonte do JDK. Embora diferentes repositórios ofereçam algumas vantagens, também apresentaram várias desvantagens operacionais. Como parte dessa mudança, diversos repositórios da floresta do JDK são consolidados em um único repositório para simplificar e otimizar o desenvolvimento.

Java 10 adicionou e removeu (Sim, não é um erro de digitação) APIs. O Java 9 introduziu uma depreciação aprimorada onde certas APIs foram marcadas para serem removidas em lançamentos futuros. APIs Removidas: Você pode encontrar as APIs removidas aqui. APIs Adicionadas: Foram adicionadas 73 novas APIs no Java 10. Você pode encontrar as APIs adicionadas juntamente com a comparação aqui. Vamos ver algumas adições:

  • Interfaces List, Map & Set são adicionadas com um método estático copyOf(Collection). Ele retorna uma List, Map ou Set imodificável contendo as entradas fornecidas. Para uma List, se a List fornecida for modificada posteriormente, a List retornada não refletirá tais modificações.
  • Optional & suas variações primitivas recebem um método orElseThrow(). Isso é exatamente igual a get(), no entanto, a documentação do Java afirma que é uma alternativa preferida a get().
  • A classe Collectors recebe vários métodos para coletar coleções imodificáveis (Set, List, Map)
List actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// Nova API adicionada - Cria uma List imodificável a partir de uma List.
List copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Irá gerar uma
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
		
String str = "";
Optional name = Optional.ofNullable(str);
// Nova API adicionada - é a opção preferida em relação ao método get()
name.orElseThrow(); // same as name.get()  

// Nova API adicionada - Collectors.toUnmodifiableList
List collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Irá gerar uma
// UnsupportedOperationException

Conclusão

Neste artigo, passamos pelas diferentes novas adições de recursos do Java 10. Se você acha que algo importante foi deixado de fora aqui, por favor nos avise através dos comentários. Como de costume, você pode conferir o código completo no GitHub aqui.

Source:
https://www.digitalocean.com/community/tutorials/java-10-features