Java 9 Nye funksjoner
1. Oversikt
Java 9 kommer med et rikt funksjonssett. Selv om det ikke er noen nye språkkonsepter, vil nye APIer og diagnostiske kommandoer definitivt være interessante for utviklere.
I denne oppskriften vil vi se raskt på høyt nivå på noen av de nye funksjonene; en full liste over nye funksjoner er tilgjengelig her.
2. Modular System - Jigsaw Project
La oss starte med den store - å bringe modularitet inn i Java-plattformen.
Et modulært system gir funksjoner som ligner på OSGi framework-systemet. Moduler har et konsept med avhengigheter, kan eksportere en offentlig API og holde implementeringsdetaljer skjult / privat.
En av hovedmotivasjonene her er å tilby modulær JVM, som kan kjøres på enheter med mye mindre tilgjengelig minne. JVM kan bare kjøre med de modulene og API-ene som kreves av applikasjonen. Sjekk ut denne lenken for en beskrivelse av hva disse modulene er.
Også JVM interne (implementerings) APIer som com. sol. * er ikke lenger tilgjengelig fra applikasjonskode.
Enkelt sagt, modulene kommer til å bli beskrevet i en fil som heter module-info.java plassert øverst i Java-kodehierarkiet:
modul com.baeldung.java9.modules.car {krever com.baeldung.java9.modules.engines; eksporterer com.baeldung.java9.modules.car.handling; }
Modulen vår bil krever modul motor å kjøre og eksportere en pakke til håndtering.
For mer detaljert eksempel, sjekk OpenJDK Project Jigsaw: Module System Quick-Start Guide.
3. En ny HTTP-klient
En etterlengtet erstatning for det gamle HttpURLConnection.
Den nye API-en ligger under java.net.http pakke.
Den skal støtte både HTTP / 2-protokoll og WebSocket-håndtrykk, med ytelse som skal være sammenlignbar med Apache HttpClient, Netty og Jetty.
La oss se på denne nye funksjonaliteten ved å opprette og sende en enkel HTTP-forespørsel.
Oppdatering: HTTP-klienten JEP flyttes til inkubatormodulen, så den er ikke lenger tilgjengelig i pakken java.net.http og er i stedet tilgjengelig under jdk.inkubator.http.
3.1. Rask GET-forespørsel
API bruker Builder-mønsteret, noe som gjør det veldig enkelt for rask bruk:
HttpRequest-forespørsel = HttpRequest.newBuilder () .uri (ny URI ("// postman-echo.com/get")) .GET () .build (); HttpResponse respons = HttpClient.newHttpClient () .send (forespørsel, HttpResponse.BodyHandler.asString ());
4. Prosess-API
Prosess-API er forbedret for å kontrollere og administrere operativsystemprosesser.
4.1. Prosessere informasjon
Klassen java.lang.ProcessHandle inneholder de fleste av de nye funksjonene:
ProcessHandle self = ProcessHandle.current (); lang PID = self.getPid (); ProcessHandle.Info procInfo = self.info (); Valgfri args = procInfo.arguments (); Valgfri cmd = procInfo.commandLine (); Valgfri starttid = procInfo.startInstant (); Valgfri cpuUsage = procInfo.totalCpuDuration ();
De nåværende metoden returnerer et objekt som representerer en prosess for å kjøre JVM. De Info underklasse gir detaljer om prosessen.
4.2. Ødelegge prosesser
Nå - la oss stoppe alle barneprosesser som kjører ødelegge():
childProc = ProcessHandle.current (). barn (); childProc.forEach (procHandle -> {assertTrue ("Kunne ikke drepe prosessen" + procHandle.getPid (), procHandle.destroy ());});
5. Små språkendringer
5.1. Prøv-med-ressurser
I Java 7, prøv-med-ressurser syntaks krever at en ny variabel deklareres for hver ressurs som administreres av uttalelsen.
I Java 9 er det en ytterligere forbedring: Hvis ressursen refereres til av en endelig eller effektiv endelig variabel, kan en prøve-med-ressurs-uttalelse administrere en ressurs uten at en ny variabel blir erklært:
MyAutoCloseable mac = ny MyAutoCloseable (); prøv (mac) {// gjør noen ting med mac} prøv (nye MyAutoCloseable () {} .finalWrapper.finalCloseable) {// gjør noen ting med finalCloseable} fangst (Unntak eks) {}
5.2. Utvidelse av diamantoperatør
Nå kan vi bruke diamantoperatør i forbindelse med anonyme indre klasser:
FooClass fc = ny FooClass (1) {// anonym indre klasse}; FooClass fc0 = ny FooClass (1) {// anonym indre klasse}; FooClass fc1 = ny FooClass (1) {// anonym indre klasse};
5.3. Grensesnitt privat metode
Grensesnitt i den kommende JVM-versjonen kan ha privat metoder, som kan brukes til å dele lange standardmetoder:
grensesnitt InterfaceWithPrivateMethods {privat statisk streng statisk privat () {returner "statisk privat"; } privat streng forekomst privat () {returner "forekomst privat"; } standard ugyldig kontroll () {Strengresultat = staticPrivate (); InterfaceWithPrivateMethods pvt = ny InterfaceWithPrivateMethods () {// anonym klasse}; resultat = pvt.instancePrivate (); }}}
6. JShell Command Line Tool
JShell er leseeval – utskriftsløkke - REPL for kort.
Enkelt sagt, det er et interaktivt verktøy for å evaluere erklæringer, uttalelser og uttrykk for Java, sammen med et API. Det er veldig praktisk å teste små kodebiter, som ellers krever å opprette en ny klasse med hoved- metode.
De jshell kjørbar selv kan bli funnet i / søppel mappe:
jdk-9 \ bin> jshell.exe | Velkommen til JShell - Versjon 9 | For en introduksjonstype: / help intro jshell> "Dette er min lange streng. Jeg vil ha en del av den" .substring (8,19); $ 5 ==> "min lange streng"
Det interaktive skallet kommer med historie og automatisk fullføring; det gir også funksjonalitet som lagring til og lasting fra filer, alle eller noen av de skriftlige uttalelsene:
jshell> / lagre c: \ utvikle \ JShell_hello_world.txt jshell> / åpne c: \ utvikle \ JShell_hello_world.txt Hei JShell!
Kodebiter utføres når filen lastes inn.
7. JCMD-underkommandoer
La oss utforske noen av de nye underkommandoene i jcmd kommandolinjeverktøy. Vi får en liste over alle klassene som er lastet inn i JVM og deres arvestruktur.
I eksemplet nedenfor kan vi se hierarkiet til java.lang.Socket lastet inn i JVM som kjører Eclipse Neon:
jdk-9 \ bin> jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 14056: java.lang.Object / null | --java.net.Socket / null | implementerer java.io.Closeable / null (erklært intf) | implementerer java.lang.AutoCloseable / null (arvet intf) | | --org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket | | implementerer java.lang.AutoCloseable / null (arvet intf) | | implementerer java.io.Closeable / null (arvet intf) | | --javax.net.ssl.SSLSocket / null | | implementerer java.lang.AutoCloseable / null (arvet intf) | | implementerer java.io.Closeable / null (arvet intf)
Den første parameteren for jcmd kommando er prosess-id (PID) for JVM som vi vil kjøre kommandoen på.
En annen interessant underkommando er set_vmflag. Vi kan endre noen JVM-parametere online, uten at vi trenger å starte JVM-prosessen på nytt og endre oppstartsparametrene.
Du kan finne ut alle tilgjengelige VM-flagg med underkommando jcmd 14056 VM.flags -all
8. М-Multi-Resolution Image API
Grensesnittet java.awt.image.MultiResolutionImage innkapsler et sett med bilder med forskjellige oppløsninger til et enkelt objekt. Vi kan hente en oppløsningsspesifikk bildevariant basert på en gitt DPI-beregning og sett med bildetransformasjoner eller hente alle variantene i bildet.
De java.awt.Grafikk klasse får variant fra et bilde med flere oppløsninger basert på gjeldende DPI-beregning og eventuelle anvendte transformasjoner.
Klassen java.awt.image.BaseMultiResolutionImage gir grunnleggende implementering:
BufferedImage [] resolutionVariants = .... MultiResolutionImage bmrImage = ny BaseMultiResolutionImage (baseIndex, resolutionVariants); BildetestRVImage = bmrImage.getResolutionVariant (16, 16); assertSame ("Bilder skal være de samme", testRVImage, resolutionVariants [3]);
9. Variable håndtak
API-et ligger under java.lang.invoke og består av VarHandle og Metode Håndtak. Det gir ekvivalenter av java.util.concurrent.atomic og sun.misc. usikre operasjoner på objektfelt og matriseelementer med lignende ytelse.
Med Java 9 Modular system tilgang til sun.misc. usikre vil ikke være mulig fra applikasjonskoden.
10. Publiser-abonner rammeverk
Klassen java.util.concurrent.Flow gir grensesnitt som støtter Reactive Streams publish-subscribe-rammeverket. Disse grensesnittene støtter interoperabilitet på tvers av en rekke asynkrone systemer som kjører på JVM-er.
Vi kan bruke verktøyklasse Innlevering Forlag for å lage tilpassede komponenter.
11. Enhetlig JVM-logging
Denne funksjonen introduserer et felles loggingssystem for alle komponenter i JVM. Det gir infrastrukturen for å logge, men det legger ikke til de faktiske loggeanropene fra alle JVM-komponenter. Det legger heller ikke til logging til Java-kode i JDK.
Loggingsrammeverket definerer et sett med koder - for eksempel, gc, kompilator, tråderosv. Vi kan bruke kommandolinjeparameteren -Xlog for å slå på logging under oppstart.
La oss logge meldinger merket med ‘gc’ tag ved hjelp av ‘debug’ nivå til en fil som heter ‘gc.txt’ uten dekorasjoner:
java -Xlog: gc = feilsøking: fil = gc.txt: ingen ...
-Xlog: hjelp vil sende mulige alternativer og eksempler. Loggkonfigurasjon kan endres kjøretid ved hjelp av jcmd kommando. Vi skal sette GC-logger til info og omdirigere dem til en fil - gc_logs:
jcmd 9615 VM.log-utgang = gc_logs hva = gc
12. Nye APIer
12.1. Uforanderlig sett
java.util.Set.of () - skaper et uforanderlig sett med gitte elementer. I Java 8 vil det kreve flere linjer med kode å lage et sett med flere elementer. Nå kan vi gjøre det så enkelt som:
Sett strKeySet = Set.of ("key1", "key2", "key3");
De Sett returnert av denne metoden er JVM intern klasse: java.util.ImmutableCollections.SetN, som strekker seg offentlig java.util.AbstractSet. Det er uforanderlig - hvis vi prøver å legge til eller fjerne elementer, blir et Ikke-støttetOperationException vil bli kastet.
Du kan også konvertere en hel matrise til en Sett med samme metode.
12.2. Valgfritt å streame
java.util.Optional.stream () gir oss en enkel måte å bruke kraften til Streams på valgfrie elementer:
Liste filteredList = listOfOptionals.stream () .flatMap (Valgfritt :: stream) .collect (Collectors.toList ());
13. Konklusjon
Java 9 kommer med en modulær JVM og mange andre nye og varierte forbedringer og funksjoner.
Du kan finne kildekoden for eksemplene på GitHub.