Java 9 nieuwe functies

1. Overzicht

Java 9 wordt geleverd met een uitgebreide set functies. Hoewel er geen nieuwe taalconcepten zijn, zullen nieuwe API's en diagnostische commando's zeker interessant zijn voor ontwikkelaars.

In dit artikel gaan we een snelle blik op hoog niveau werpen op enkele van de nieuwe functies; een volledige lijst met nieuwe functies is hier beschikbaar.

2. Modulair systeem - Jigsaw-project

Laten we beginnen met de grote: modulariteit in het Java-platform brengen.

Een modulair systeem biedt mogelijkheden die vergelijkbaar zijn met het systeem van OSGi-framework. Modules hebben een concept van afhankelijkheden, kunnen een openbare API exporteren en implementatiedetails verborgen / privé houden.

Een van de belangrijkste redenen hiervoor is om modulaire JVM te bieden, die kan worden uitgevoerd op apparaten met veel minder beschikbaar geheugen. De JVM kan alleen worden uitgevoerd met die modules en API's die vereist zijn voor de applicatie. Bekijk deze link voor een beschrijving van wat deze modules zijn.

Ook JVM interne (implementatie) API's zoals com.zon. * zijn niet langer toegankelijk via de applicatiecode.

Simpel gezegd, de modules worden beschreven in een bestand met de naam module-info.java bevindt zich bovenaan de hiërarchie van de Java-code:

module com.baeldung.java9.modules.car {vereist com.baeldung.java9.modules.engines; exporteert com.baeldung.java9.modules.car.handling; } 

Onze module auto vereist module motor om een ​​pakket uit te voeren en te exporteren voor behandeling.

Raadpleeg voor een meer diepgaand voorbeeld OpenJDK Project Jigsaw: Quick-Start Guide voor modulesysteem.

3. Een nieuwe HTTP-client

Een langverwachte vervanging van het oude HttpURLConnection.

De nieuwe API bevindt zich onder de java.net.http pakket.

Het zou zowel het HTTP / 2-protocol als de WebSocket-handshake moeten ondersteunen, met prestaties die vergelijkbaar zouden moeten zijn met de Apache HttpClient, Netty en Jetty.

Laten we deze nieuwe functionaliteit eens bekijken door een eenvoudig HTTP-verzoek te maken en te verzenden.

Update: de HTTP Client JEP wordt verplaatst naar de Incubator-module, dus deze is niet langer beschikbaar in het pakket java.net.http en in plaats daarvan is beschikbaar onder jdk.incubator.http.

3.1. Snel GET Request

De API maakt gebruik van het Builder-patroon, wat het heel gemakkelijk maakt voor snel gebruik:

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

4. API verwerken

De proces-API is verbeterd voor het besturen en beheren van besturingssysteemprocessen.

4.1. Proces informatie

De klas java.lang.ProcessHandle bevat de meeste nieuwe functionaliteiten:

ProcessHandle self = ProcessHandle.current (); lange PID = self.getPid (); ProcessHandle.Info procInfo = self.info (); Optioneel args = procInfo.arguments (); Optioneel cmd = procInfo.commandLine (); Optioneel startTime = procInfo.startInstant (); Optioneel cpuUsage = procInfo.totalCpuDuration ();

De actueel method retourneert een object dat een proces vertegenwoordigt waarin JVM momenteel wordt uitgevoerd. De Info subklasse geeft details over het proces.

4.2. Vernietigende processen

Laten we nu alle actieve onderliggende processen stoppen met vernietigen():

childProc = ProcessHandle.current (). kinderen (); childProc.forEach (procHandle -> {assertTrue ("Kon proces niet doden" + procHandle.getPid (), procHandle.destroy ());});

5. Kleine taalwijzigingen

5.1. Probeer met bronnen

In Java 7 is het probeer-met-middelen syntaxis vereist dat een nieuwe variabele wordt gedeclareerd voor elke resource die door de instructie wordt beheerd.

In Java 9 is er een extra verfijning: als naar de bron wordt verwezen door een laatste of effectief laatste variabele, kan een try-with-resources-instructie een bron beheren zonder dat een nieuwe variabele wordt gedeclareerd:

MyAutoCloseable mac = nieuwe MyAutoCloseable (); try (mac) {// doe wat dingen met mac} probeer (new MyAutoCloseable () {} .finalWrapper.finalCloseable) {// doe wat dingen met finalCloseable} catch (Exception ex) {} 

5.2. Diamond Operator-extensie

Nu kunnen we de diamantoperator gebruiken in combinatie met anonieme innerlijke klassen:

FooClass fc = nieuwe FooClass (1) {// anonieme innerlijke klasse}; FooClass fc0 = nieuwe FooClass (1) {// anonieme innerlijke klasse}; FooClass fc1 = nieuwe FooClass (1) {// anonieme innerlijke klasse}; 

5.3. Interfacemethode

Interfaces in de komende JVM-versie kunnen hebben privaat methoden, die kunnen worden gebruikt om lange standaardmethoden te splitsen:

interface InterfaceWithPrivateMethods {privé statische String staticPrivate () {retourneer "statisch privé"; } private String instancePrivate () {retourneer "instance private"; } standaard ongeldige controle () {String resultaat = staticPrivate (); InterfaceWithPrivateMethods pvt = nieuwe InterfaceWithPrivateMethods () {// anonieme klasse}; resultaat = pvt.instancePrivate (); }}}

6. JShell-opdrachtregelprogramma

JShell is read-eval-print loop - afgekort REPL.

Simpel gezegd, het is een interactieve tool om declaraties, statements en uitdrukkingen van Java te evalueren, samen met een API. Het is erg handig voor het testen van kleine codefragmenten, waarvoor anders een nieuwe klasse met de hoofd methode.

De jshell executable zelf is te vinden in / bin map:

jdk-9 \ bin> jshell.exe | Welkom bij JShell - Versie 9 | Voor een introductie typ je: / help intro jshell> "Dit is mijn lange string. Ik wil er een deel van" .substring (8,19); $ 5 ==> "mijn lange string"

De interactieve shell wordt geleverd met geschiedenis en automatische aanvulling; het biedt ook functionaliteit zoals het opslaan naar en laden van bestanden, alle of enkele van de schriftelijke verklaringen:

jshell> / save c: \ Develop \ JShell_hello_world.txt jshell> / open c: \ Develop \ JShell_hello_world.txt Hallo JShell! 

Codefragmenten worden uitgevoerd bij het laden van het bestand.

7. JCMD-subopdrachten

Laten we eens kijken naar enkele van de nieuwe subopdrachten in jcmd opdrachtregelprogramma. We krijgen een lijst met alle klassen die in de JVM zijn geladen en hun overervingsstructuur.

In het onderstaande voorbeeld zien we de hiërarchie van java.lang.Socket geladen in JVM met Eclipse Neon:

jdk-9 \ bin> jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 14056: java.lang.Object / null | --java.net.Socket / null | implementeert java.io.Closeable / null (gedeclareerd intf) | implementeert java.lang.AutoCloseable / null (overgenomen intf) | | --org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket | | implementeert java.lang.AutoCloseable / null (overgenomen intf) | | implementeert java.io.Closeable / null (erfelijke intf) | | --javax.net.ssl.SSLSocket / null | | implementeert java.lang.AutoCloseable / null (overgenomen intf) | | implementeert java.io.Closeable / null (erfelijke intf) 

De eerste parameter van jcmd commando is de proces-id (PID) van de JVM waarop we de opdracht willen uitvoeren.

Een ander interessant subcommando is set_vmflag. We kunnen enkele JVM-parameters online wijzigen, zonder dat het JVM-proces opnieuw hoeft te worden gestart en de opstartparameters ervan moeten worden aangepast.

U kunt alle beschikbare VM-vlaggen vinden met een subcommando jcmd 14056 VM.flags -all

8. М Multi-resolutie beeld-API

De interface java.awt.image.MultiResolutionImage kapselt een reeks afbeeldingen met verschillende resoluties in een enkel object in. We kunnen een resolutiespecifieke afbeeldingsvariant ophalen op basis van een bepaalde DPI-metriek en een reeks afbeeldingstransformaties, of we kunnen alle varianten in de afbeelding ophalen.

De java.awt.Graphics klasse krijgt een variant van een afbeelding met meerdere resolutie op basis van de huidige DPI-metriek van het display en eventuele toegepaste transformaties.

De klas java.awt.image.BaseMultiResolutionImage biedt basisimplementatie:

BufferedImage [] resolutionVariants = .... MultiResolutionImage bmrImage = nieuwe BaseMultiResolutionImage (baseIndex, resolutionVariants); Afbeelding testRVImage = bmrImage.getResolutionVariant (16, 16); assertSame ("Afbeeldingen moeten hetzelfde zijn", testRVImage, resolutionVariants [3]); 

9. Variabele handgrepen

De API bevindt zich onder java.lang.invoke en bestaat uit VarHandle en Methode: Handvatten. Het biedt equivalenten van java.util.concurrent.atomic en zon.misc. onveilig bewerkingen op objectvelden en array-elementen met vergelijkbare prestaties.

Met Java 9 Modular-systeemtoegang tot zon.misc. onveilig zal niet mogelijk zijn vanaf de applicatiecode.

10. Publiceer-abonneerkader

De klas java.util.concurrent.Flow biedt interfaces die het Reactive Streams publish-subscribe framework ondersteunen. Deze interfaces ondersteunen interoperabiliteit tussen een aantal asynchrone systemen die op JVM's draaien.

We kunnen gebruiksklasse gebruiken Indiening Uitgever om gebruikerscomponenten te maken.

11. Uniforme JVM-logboekregistratie

Deze functie introduceert een gemeenschappelijk logboeksysteem voor alle componenten van de JVM. Het biedt de infrastructuur om de logboekregistratie uit te voeren, maar het voegt niet de daadwerkelijke logboekoproepen van alle JVM-componenten toe. Het voegt ook geen logboekregistratie toe aan Java-code in de JDK.

Het framework voor logboekregistratie definieert een set van tags - bijvoorbeeld, gc, compiler, draden, enz. We kunnen de opdrachtregelparameter gebruiken -Xlog om logboekregistratie in te schakelen tijdens het opstarten.

Laten we berichten die zijn getagd met de ‘gc'-tag met het‘ debug'-niveau vastleggen in een bestand met de naam ‘gc.txt 'zonder versieringen:

java -Xlog: gc = debug: bestand = gc.txt: geen ...

-Xlog: help geeft mogelijke opties en voorbeelden weer. Logboekconfiguratie kan runtime worden gewijzigd met jcmd opdracht. We gaan GC-logboeken instellen op info en ze omleiden naar een bestand - gc_logs:

jcmd 9615 VM.log output = gc_logs wat = gc

12. Nieuwe API's

12.1. Onveranderlijke set

java.util.Set.of () - creëert een onveranderlijke set van bepaalde elementen. In Java 8 zou het maken van een set van verschillende elementen meerdere regels code vereisen. Nu kunnen we het zo simpel doen als:

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

De Set geretourneerd door deze methode is de interne JVM-klasse: java.util.ImmutableCollections.SetN, die het publiek uitbreidt java.util.AbstractSet. Het is onveranderlijk - als we proberen elementen toe te voegen of te verwijderen, wordt een UnsupportedOperationException zal worden gegooid.

U kunt ook een hele array converteren naar een Set met dezelfde methode.

12.2. Optioneel om te streamen

java.util.Optional.stream () geeft ons een gemakkelijke manier om de kracht van Streams op optionele elementen te gebruiken:

Lijst gefilterdeList = listOfOptionals.stream () .flatMap (Optioneel :: stream) .collect (Collectors.toList ()); 

13. Conclusie

Java 9 wordt geleverd met een modulaire JVM en tal van andere nieuwe en diverse verbeteringen en functies.

Je kunt de broncode voor de voorbeelden vinden op GitHub.