Java 10 é o lançamento mais rápido de uma versão do Java em sua história de 23 anos. 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 funcionalidades 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 sua mudança para um novo ritmo de lançamento de 6 meses para o Java. Ele 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 principal e sustentado pela Oracle e será direcionada a cada 3 anos. Cada lançamento do Java é modelado após uma ou duas características principais, essas características impulsionam o lançamento. Qualquer obstáculo adia o lançamento e atrasa a chegada ao mercado. O Projeto Jigsaw foi uma característica importante do Java 9, que adiou 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 funcionalidades que são aprovadas são embarcadas no trem; caso contrário, elas esperam pelo próximo trem programado.
Oracle JDK vs Open JDK
Para ser mais amigável ao desenvolvedor, 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, quando 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 a longo prazo. Isso é uma movimentação 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 prendem à versão até onde podem. A adoção da indústria para o Java 6 foi maior do que para o Java 7 e então 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 espiada nas funcionalidades disponíveis no Java 10.
Com a adoção do ciclo de lançamento baseado em tempo, a Oracle alterou o esquema de strings 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 atuais e futuros. O novo padrão do número da versão é: $FEATURE.$INTERIM.$UPDATE.$PATCH
$FEATURE: o contador será incrementado a cada 6 meses e basear-se-á 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 compatíveis e melhorias, mas sem alterações incompatíveis. Normalmente, 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 no 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 daí. O lançamento de abril de 2018 é o JDK 10.0.1, o lançamento de julho é o 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 contagem 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” porque não há outro contador que seja diferente de 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 novidade 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 de loops for aprimorados ou índices
- Locais declarados em loops 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 saber mais sobre isso em nossa postagem exclusiva sobre inferência de tipo de variável local no Java 10.13. ### Compilador JIT Experimental Baseado em Java (JEP 317)
Essa funcionalidade permite que o compilador JIT baseado em Java, Graal, seja usado como um compilador JIT experimental na plataforma Linux/x64. Esta é, de longe, a inclusão mais futurista na lista de recursos do Java 10. O Graal foi introduzido no Java 9. É uma alternativa ao compilador JIT ao qual estamos acostumados. É um plug-in para a JVM, o que significa que o compilador JIT não está vinculado à JVM e pode ser conectado dinamicamente e substituído por qualquer outro plug-in que esteja em conformidade com o JVMCI (Interface do 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 então o compilador JIT pode ser usado dentro da JVM para aprimorar o desempenho por meio da otimização de código em tempo real. O Graal é uma reescrita completa do compilador JIT em Java do zero. O compilador JIT anterior foi escrito em c++. Ele é considerado um dos estágios finais de evolução para qualquer linguagem de programação. Você pode alternar para o Graal com os seguintes parâmetros da JVM:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
Você pode aprender mais sobre o Graal na apresentação de Chris Seaton.
Essa funcionalidade ajuda a melhorar a pegada inicial da inicialização, estende o recurso existente de Compartilhamento de Dados de Classe (“CDS”) para permitir que classes de aplicativos sejam colocadas no arquivo compartilhado. A JVM, ao iniciar, executa algumas etapas preliminares, uma das quais é carregar classes na memória. Se houver vários JARs com várias classes, então a demora no primeiro pedido é claramente visível. Isso se torna um problema com a arquitetura sem servidor, onde o tempo de inicialização é crítico. Para reduzir o tempo de inicialização do aplicativo, pode-se usar o compartilhamento de dados de classe de aplicativo. 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 arquivar: Use o lançador 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
Criando o arquivo AppCDS: Use o lançador Java para criar o arquivo da lista de arquivos a serem usados para o CDS do aplicativo, 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
Usando o arquivo AppCDS: Use o lançador Java com os seguintes parâmetros para usar o CDS do aplicativo.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
O coletor de lixo G1 foi definido como padrão no JDK 9. O coletor de lixo G1 evita qualquer coleta completa de lixo, mas quando as threads concorrentes para coleta não conseguem recuperar a memória rápido o suficiente, a experiência do usuário é afetada. Esta mudança melhora a latência máxima do G1 tornando a coleta completa paralela. O algoritmo de marcação, varredura e compactação do coletor G1 é paralelizado como parte desta mudança e será acionado quando as threads concorrentes para coleta não conseguirem recuperar a memória rápido o suficiente. 25. ### Interface do Coletor de Lixo (JEP 304)
Esta JEP é uma mudança futurística. Ela melhora o isolamento de código dos diferentes coletores de lixo, introduzindo uma Interface Comum de Coletor de Lixo. Esta mudança fornece melhor modularidade ao Código Interno do GC. Isso ajudará no futuro a adicionar novos GC sem alterar a base de código existente, também ajudará na remoção ou manutenção dos GC anteriores. 26. ### Extensões Adicionais de Tags de Idioma Unicode (JEP 314)
Esta funcionalidade melhora o java.util.Locale e APIs relacionadas para implementar extensões adicionais Unicode de tags de idioma BCP 47. A partir do Java SE 9, as extensões de tag de idioma BCP 47 U suportadas são “ca” e “nu”. Esta 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 dar suporte a essas 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
Para promover o OpenJDK e torná-lo mais atraente para os usuários da comunidade, este recurso fornece um conjunto padrão de certificados da 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 iguais. Componentes críticos de segurança, como TLS, funcionarão por padrão nas compilações do OpenJDK daqui para frente. 30. ### Handshakes Locais a Threads (JEP 312)
Esta é uma característica interna da JVM para melhorar o desempenho. Uma operação de handshake é uma chamada de retorno que é executada para cada JavaThread enquanto esse thread está em um estado de safepoint. A chamada de retorno é executada pelo próprio thread ou pelo thread da VM mantendo o thread em um estado bloqueado. Este recurso fornece uma maneira de executar uma chamada de retorno em threads sem realizar um safepoint global da VM. Torna possível e barato interromper threads individuais e não apenas todas ou nenhuma. 31. ### Alocação de Heap em Dispositivos de Memória Alternativos (JEP 316)
Aplicativos tornaram-se exigentes em termos de memória, há um aumento em aplicativos nativos de nuvem, bancos de dados em memória e aplicativos de streaming. Para atender a esses serviços, existem várias arquiteturas de memória disponíveis. Este recurso 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 tenham as mesmas semânticas que a DRAM, incluindo as semânticas de operações atômicas, e, portanto, podem ser usados em vez da DRAM para o heap de objetos sem qualquer alteração no código do aplicativo existente.32. ### Remover a Ferramenta de Geração de Cabeçalhos Nativos – javah (JEP 313)
Esta é uma alteração de limpeza para remover a ferramenta javah do JDK. A funcionalidade da ferramenta é adicionada no javac
como parte do JDK 8, o que permite escrever arquivos de cabeçalho nativos no tempo de compilação, tornando o javah
inútil.35. ### Consolidar a Floresta do JDK em um Único Repositório (JEP 296)
Ao longo dos anos, houve vários repositórios Mercurial para o código-fonte do JDK. Diferentes repositórios fornecem algumas vantagens, mas também tiveram várias desvantagens operacionais. Como parte dessa mudança, numerosos repositórios da floresta do JDK são combinados em um único repositório para simplificar e otimizar o desenvolvimento.36. ### Mudanças na API
Java 10 adicionou e removeu (Sim, não é um erro de digitação) APIs. O Java 9 introduziu aprimoramentos na depreciação, onde certas APIs foram marcadas para serem removidas em futuras versões. 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 uma comparação aqui. Vamos examinar algumas adições:
- Foram adicionadas interfaces List, Map & Set com um método estático copyOf(Collection). Ela retorna uma List, Map ou Set não modificá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 e suas variações primitivas recebem um método orElseThrow(). Isso é exatamente igual ao get(), no entanto, a documentação Java afirma que é uma alternativa preferida ao get().
- A classe Collectors recebe vários métodos para coletar coleções não modificá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 não modificá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, percorremos as diferentes adições de novos 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