Novos recursos do Java 9
1. Visão geral
O Java 9 vem com um rico conjunto de recursos. Embora não haja novos conceitos de linguagem, novas APIs e comandos de diagnóstico serão definitivamente interessantes para os desenvolvedores.
Neste artigo, daremos uma olhada rápida e de alto nível em alguns dos novos recursos; uma lista completa de novos recursos está disponívelhere.
2. Sistema Modular - Projeto Jigsaw
Vamos começar com o maior - trazer modularidade para a plataforma Java.
Um sistema modular fornece recursos semelhantes ao sistema da estrutura OSGi. Os módulos têm um conceito de dependências, podem exportar uma API pública e manter os detalhes da implementação ocultos / privados.
Uma das principais motivações aqui é fornecer JVM modular, que pode ser executado em dispositivos com muito menos memória disponível. A JVM pode ser executada apenas com os módulos e APIs exigidos pelo aplicativo. Verifiquethis link para obter uma descrição do que são esses módulos.
Além disso, APIs (implementação) internas da JVM comocom.sun.* não são mais acessíveis a partir do código do aplicativo.
Simplificando, os módulos serão descritos em um arquivo chamadomodule-info.java localizado no topo da hierarquia do código java:
module com.example.java9.modules.car {
requires com.example.java9.modules.engines;
exports com.example.java9.modules.car.handling;
}
Nosso módulocar requer o móduloengine para ser executado e exporta um pacote parahandling.
Para exemplos mais detalhados, verifique OpenJDKProject Jigsaw: Module System Quick-Start Guide.
3. Um Novo Cliente HTTP
Uma substituição muito esperada do antigoHttpURLConnection.
A nova API está localizada no pacotejava.net.http.
Deve ser compatível com o handshakeHTTP/2 protocoleWebSocket, com desempenho que deve ser comparável aoApache HttpClient,NettyeJetty.
Vamos dar uma olhada nessa nova funcionalidade criando e enviando uma solicitação HTTP simples.
Atualização: OHTTP Client JEP está sendo movido para o módulo Incubator, portanto não está mais disponível no pacotejava.net.http e em vez disso está disponível emjdk.incubator.http.
3.1. Solicitação GET rápida
A API usa o padrão Builder, o que facilita muito o uso rápido:
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/get"))
.GET()
.build();
HttpResponse response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandler.asString());
4. API de processo
A API do processo foi aprimorada para controlar e gerenciar processos do sistema operacional.
4.1. Processo de informação
A classejava.lang.ProcessHandle contém a maioria das novas funcionalidades:
ProcessHandle self = ProcessHandle.current();
long PID = self.getPid();
ProcessHandle.Info procInfo = self.info();
Optional args = procInfo.arguments();
Optional cmd = procInfo.commandLine();
Optional startTime = procInfo.startInstant();
Optional cpuUsage = procInfo.totalCpuDuration();
O métodocurrent retorna um objeto que representa um processo de JVM atualmente em execução. A subclasseInfo fornece detalhes sobre o processo.
4.2. Processos de Destruição
Agora - vamos parar todos os processos filho em execução usandodestroy():
childProc = ProcessHandle.current().children();
childProc.forEach(procHandle -> {
assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());
});
5. Pequenas modificações de linguagem
5.1. Experimente com recursos
No Java 7, a sintaxetry-with-resources requer que uma nova variável seja declarada para cada recurso sendo gerenciado pela instrução.
No Java 9, há um refinamento adicional: se o recurso for referenciado por uma variável final ou efetivamente final, uma instrução try-with-resources poderá gerenciar um recurso sem que uma nova variável seja declarada:
MyAutoCloseable mac = new MyAutoCloseable();
try (mac) {
// do some stuff with mac
}
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
// do some stuff with finalCloseable
} catch (Exception ex) { }
5.2. Diamond Operator Extension
Agora podemos usar o operador diamond em conjunto com classes internas anônimas:
FooClass fc = new FooClass<>(1) { // anonymous inner class
};
FooClass extends Integer> fc0 = new FooClass<>(1) {
// anonymous inner class
};
FooClass> fc1 = new FooClass<>(1) { // anonymous inner class
};
5.3. Método privado de interface
As interfaces na próxima versão da JVM podem ter métodosprivate, que podem ser usados para dividir métodos padrão longos:
interface InterfaceWithPrivateMethods {
private static String staticPrivate() {
return "static private";
}
private String instancePrivate() {
return "instance private";
}
default void check() {
String result = staticPrivate();
InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {
// anonymous class
};
result = pvt.instancePrivate();
}
}}
6. Ferramenta de linha de comando JShell
JShell é um loop de leitura-avaliação-impressão - REPL para breve.
Simplificando, é uma ferramenta interativa para avaliar declarações, instruções e expressões de Java, junto com uma API. É muito conveniente para testar pequenos fragmentos de código, que de outra forma requerem a criação de uma nova classe com o métodomain.
O próprio executáveljshell pode ser encontrado na pasta<JAVA_HOME>/bin:
jdk-9\bin>jshell.exe
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> "This is my long string. I want a part of it".substring(8,19);
$5 ==> "my long string"
O shell interativo vem com histórico e preenchimento automático; Ele também fornece funcionalidades como salvar e carregar arquivos, todas ou algumas das instruções escritas:
jshell> /save c:\develop\JShell_hello_world.txt
jshell> /open c:\develop\JShell_hello_world.txt
Hello JShell!
Os trechos de código são executados no carregamento do arquivo.
7. Subcomandos JCMD
Vamos explorar alguns dos novos subcomandos no utilitário de linha de comandojcmd. Obteremos uma lista de todas as classes carregadas na JVM e sua estrutura de herança.
No exemplo abaixo, podemos ver a hierarquia dejava.lang.Socket carregados na JVM executando o Eclipse Neon:
jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket
14056:
java.lang.Object/null
|--java.net.Socket/null
| implements java.io.Closeable/null (declared intf)
| implements java.lang.AutoCloseable/null (inherited intf)
| |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
| | implements java.lang.AutoCloseable/null (inherited intf)
| | implements java.io.Closeable/null (inherited intf)
| |--javax.net.ssl.SSLSocket/null
| | implements java.lang.AutoCloseable/null (inherited intf)
| | implements java.io.Closeable/null (inherited intf)
O primeiro parâmetro do comandojcmd é o ID do processo (PID) da JVM na qual queremos executar o comando.
Outro subcomando interessante éset_vmflag. Podemos modificar alguns parâmetros da JVM online, sem a necessidade de reiniciar o processo da JVM e modificar seus parâmetros de inicialização.
Você pode descobrir todos os sinalizadores de VM disponíveis com o subcomandojcmd 14056 VM.flags -all
8. API de imagem multirresolução
A interfacejava.awt.image.MultiResolutionImage encapsula um conjunto de imagens com diferentes resoluções em um único objeto. Podemos recuperar uma variante de imagem específica de resolução com base em uma determinada métrica de DPI e conjunto de transformações de imagem ou recuperar todas as variantes na imagem.
A classejava.awt.Graphics obtém a variante de uma imagem de resolução múltipla com base na métrica DPI de exibição atual e quaisquer transformações aplicadas.
A classejava.awt.image.BaseMultiResolutionImage fornece implementação básica:
BufferedImage[] resolutionVariants = ....
MultiResolutionImage bmrImage
= new BaseMultiResolutionImage(baseIndex, resolutionVariants);
Image testRVImage = bmrImage.getResolutionVariant(16, 16);
assertSame("Images should be the same", testRVImage, resolutionVariants[3]);
9. Alças Variáveis
A API reside emjava.lang.invokee consiste emVarHandleeMethodHandles. Ele fornece equivalentes de operaçõesjava.util.concurrent.atomicesun.misc.Unsafe em campos de objeto e elementos de array com desempenho semelhante.
Com o sistema modular Java 9, o acesso asun.misc.Unsafe não será possível a partir do código do aplicativo.
10. Estrutura Publicar-Assinar
A classejava.util.concurrent.Flow fornece interfaces que suportam a estrutura de publicação-assinaturaReactive Streams. Essas interfaces suportam interoperabilidade em vários sistemas assíncronos em execução em JVMs.
Podemos usar a classe de utilitárioSubmissionPublisher para criar componentes personalizados.
11. Registro JVM unificado
Esse recurso apresenta um sistema de registro comum para todos os componentes da JVM. Ele fornece a infraestrutura para fazer o log, mas não inclui as chamadas de log reais de todos os componentes da JVM. Ele também não inclui o log no código Java no JDK.
A estrutura de registro define um conjunto detags - por exemplo,gc,compiler,threads, etc. Podemos usar o parâmetro de linha de comando-Xlog para ativar o registro durante a inicialização.
Vamos registrar as mensagens marcadas com a tag ‘gc 'usando o nível‘ debug ’em um arquivo chamado‘ gc.txt ’sem decorações:
java -Xlog:gc=debug:file=gc.txt:none ...
-Xlog:help produzirá opções e exemplos possíveis. A configuração de registro pode ser modificada em tempo de execução usando o comandojcmd. Vamos definir os logs do GC para informações e redirecioná-los para um arquivo - gc_logs:
jcmd 9615 VM.log output=gc_logs what=gc
12. Novas APIs
12.1. Conjunto Imutável
java.util.Set.of() - cria um conjunto imutável de um determinado elemento. No Java 8, criar um conjunto de vários elementos exigiria várias linhas de código. Agora podemos fazê-lo tão simples quanto:
Set strKeySet = Set.of("key1", "key2", "key3");
OSet retornado por este método é a classe interna da JVM:java.util.ImmutableCollections.SetN, que estende publicjava.util.AbstractSet. É imutável - se tentarmos adicionar ou remover elementos, umUnsupportedOperationException será lançado.
Você também pode converter uma matriz inteira emSet com o mesmo método.
12.2. Opcional para transmitir
java.util.Optional.stream() nos dá uma maneira fácil de usar o poder dos Streams em elementos opcionais:
List filteredList = listOfOptionals.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
13. Conclusão
O Java 9 virá com uma JVM modular e muitas outras melhorias e recursos novos e diversos.
Você pode encontrar o código-fonte dos exemplosover on GitHub.