Nuove funzionalità di Java 9

1. Panoramica

Java 9 viene fornito con un ricco set di funzionalità. Sebbene non ci siano nuovi concetti di linguaggio, nuove API e comandi diagnostici saranno sicuramente interessanti per gli sviluppatori.

In questo articolo daremo uno sguardo veloce e di alto livello ad alcune delle nuove funzionalità; un elenco completo delle nuove funzionalità è disponibile qui.

2. Sistema modulare - Progetto puzzle

Cominciamo con quello più importante: portare la modularità nella piattaforma Java.

Un sistema modulare fornisce funzionalità simili al sistema del framework OSGi. I moduli hanno un concetto di dipendenze, possono esportare un'API pubblica e mantenere i dettagli di implementazione nascosti / privati.

Una delle motivazioni principali qui è fornire una JVM modulare, che può essere eseguita su dispositivi con molta meno memoria disponibile. La JVM può essere eseguita solo con quei moduli e API che sono richiesti dall'applicazione. Dai un'occhiata a questo link per una descrizione di cosa sono questi moduli.

Inoltre, le API (implementazione) interne di JVM come com.sun. * Non sono più accessibili dal codice dell'applicazione.

In poche parole, i moduli verranno descritti in un file chiamato module-info.java situato nella parte superiore della gerarchia del codice java:

module com.baeldung.java9.modules.car { requires com.baeldung.java9.modules.engines; exports com.baeldung.java9.modules.car.handling; } 

La nostra macchina modulare richiede il motore del modulo per funzionare ed esporta un pacchetto per la gestione .

Per un esempio più approfondito, controlla OpenJDK Project Jigsaw: Module System Quick-Start Guide.

3. Un nuovo client HTTP

Una sostituzione tanto attesa del vecchio HttpURLConnection .

La nuova API si trova nel pacchetto java.net.http .

Dovrebbe supportare sia il protocollo HTTP / 2 che l'handshake WebSocket, con prestazioni che dovrebbero essere paragonabili a Apache HttpClient, Netty e Jetty.

Diamo un'occhiata a questa nuova funzionalità creando e inviando una semplice richiesta HTTP.

Aggiornamento: il JEP del client HTTP viene spostato nel modulo Incubator, quindi non è più disponibile nel pacchetto java.net.http e invece è disponibile in jdk.incubator.http.

3.1. Richiesta rapida di GET

L'API utilizza il pattern Builder, che lo rende davvero facile per un utilizzo rapido:

HttpRequest request = HttpRequest.newBuilder() .uri(new URI("//postman-echo.com/get")) .GET() .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandler.asString()); 

4. API di processo

L'API dei processi è stata migliorata per il controllo e la gestione dei processi del sistema operativo.

4.1. Informazioni sul processo

La classe java.lang.ProcessHandle contiene la maggior parte delle nuove funzionalità:

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();

Il metodo corrente restituisce un oggetto che rappresenta un processo di JVM attualmente in esecuzione. La sottoclasse Info fornisce dettagli sul processo.

4.2. Distruggere i processi

Ora, fermiamo tutti i processi figli in esecuzione usando destroy () :

childProc = ProcessHandle.current().children(); childProc.forEach(procHandle -> { assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy()); });

5. Modifiche in piccola lingua

5.1. Prova con le risorse

In Java 7, la sintassi try-with-resources richiede la dichiarazione di una nuova variabile per ogni risorsa gestita dall'istruzione.

In Java 9 c'è un ulteriore perfezionamento: se la risorsa è referenziata da una variabile finale o effettivamente finale, un'istruzione try-with-resources può gestire una risorsa senza che venga dichiarata una nuova variabile:

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. Estensione operatore Diamond

Ora possiamo usare l'operatore diamante insieme a classi interne anonime:

FooClass fc = new FooClass(1) { // anonymous inner class }; FooClass fc0 = new FooClass(1) { // anonymous inner class }; FooClass fc1 = new FooClass(1) { // anonymous inner class }; 

5.3. Metodo privato dell'interfaccia

Le interfacce nella prossima versione di JVM possono avere metodi privati , che possono essere utilizzati per suddividere metodi predefiniti lunghi:

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. Strumento da riga di comando JShell

JShell è read – eval – print loop - REPL in breve.

In poche parole, è uno strumento interattivo per valutare dichiarazioni, istruzioni ed espressioni di Java, insieme a un'API. È molto comodo per testare piccoli frammenti di codice, che altrimenti richiedono la creazione di una nuova classe con il metodo principale .

L' eseguibile jshell stesso può essere trovato nella cartella / 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"

The interactive shell comes with history and auto-completion; it also provides functionality like saving to and loading from files, all or some of the written statements:

jshell> /save c:\develop\JShell_hello_world.txt jshell> /open c:\develop\JShell_hello_world.txt Hello JShell! 

Code snippets are executed upon file loading.

7. JCMD Sub-Commands

Let's explore some of the new subcommands in jcmd command line utility. We will get a list of all classes loaded in the JVM and their inheritance structure.

In the example below we can see the hierarchy of java.lang.Socket loaded in JVM running 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) 

The first parameter of jcmd command is the process id (PID) of the JVM on which we want to run the command.

Another interesting subcommand is set_vmflag. We can modify some JVM parameters online, without the need of restarting the JVM process and modifying its startup parameters.

You can find out all the available VM flags with subcommand jcmd 14056 VM.flags -all

8. Мulti-Resolution Image API

The interface java.awt.image.MultiResolutionImage encapsulates a set of images with different resolutions into a single object. We can retrieve a resolution-specific image variant based on a given DPI metric and set of image transformations or retrieve all of the variants in the image.

The java.awt.Graphics class gets variant from a multi-resolution image based on the current display DPI metric and any applied transformations.

The class java.awt.image.BaseMultiResolutionImage provides basic implementation:

BufferedImage[] resolutionVariants = .... MultiResolutionImage bmrImage = new BaseMultiResolutionImage(baseIndex, resolutionVariants); Image testRVImage = bmrImage.getResolutionVariant(16, 16); assertSame("Images should be the same", testRVImage, resolutionVariants[3]); 

9. Variable Handles

The API resides under java.lang.invoke and consists of VarHandle and MethodHandles. It provides equivalents of java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements with similar performance.

With Java 9 Modular system access to sun.misc.Unsafe will not be possible from application code.

10. Publish-Subscribe Framework

The class java.util.concurrent.Flow provides interfaces that support the Reactive Streams publish-subscribe framework. These interfaces support interoperability across a number of asynchronous systems running on JVMs.

We can use utility class SubmissionPublisher to create custom components.

11. Unified JVM Logging

This feature introduces a common logging system for all components of the JVM. It provides the infrastructure to do the logging, but it does not add the actual logging calls from all JVM components. It also does not add logging to Java code in the JDK.

The logging framework defines a set of tags – for example, gc, compiler, threads, etc. We can use the command line parameter -Xlog to turn on logging during startup.

Let's log messages tagged with ‘gc' tag using ‘debug' level to a file called ‘gc.txt' with no decorations:

java -Xlog:gc=debug:file=gc.txt:none ...

-Xlog:help will output possible options and examples. Logging configuration can be modified runtime using jcmd command. We are going to set GC logs to info and redirect them to a file – gc_logs:

jcmd 9615 VM.log output=gc_logs what=gc

12. New APIs

12.1. Immutable Set

java.util.Set.of() – creates an immutable set of a given elements. In Java 8 creating a Set of several elements would require several lines of code. Now we can do it as simple as:

Set strKeySet = Set.of("key1", "key2", "key3");

The Set returned by this method is JVM internal class: java.util.ImmutableCollections.SetN, which extends public java.util.AbstractSet. It is immutable – if we try to add or remove elements, an UnsupportedOperationException will be thrown.

You can also convert an entire array into a Set with the same method.

12.2. Optional to Stream

java.util.Optional.stream() gives us an easy way to you use the power of Streams on Optional elements:

List filteredList = listOfOptionals.stream() .flatMap(Optional::stream) .collect(Collectors.toList()); 

13. Conclusion

Java 9 verrà fornito con una JVM modulare e molti altri miglioramenti e funzionalità nuovi e diversi.

Puoi trovare il codice sorgente per gli esempi su GitHub.