Java 9 nove značajke

1. Pregled

Java 9 dolazi s bogatim skupom značajki. Iako ne postoje novi jezični koncepti, novi API-ji i dijagnostičke naredbe zasigurno će biti zanimljivi programerima.

U ovom tekstu imat ćemo brz pogled na neke nove značajke na visokoj razini; potpuni popis novih značajki dostupan je ovdje.

2. Modularni sustav - projekt ubodne pile

Počnimo s velikim - unošenjem modularnosti u Java platformu.

Modularni sustav pruža mogućnosti slične sustavu OSGi okvira. Moduli imaju koncept ovisnosti, mogu izvesti javni API i zadržati detalje o implementaciji skrivenim / privatnim.

Jedna od glavnih motivacija ovdje je pružanje modularnog JVM-a koji može raditi na uređajima s puno manje dostupne memorije. JVM se mogao izvoditi samo s onim modulima i API-ima koji su potrebni aplikaciji. Pogledajte ovu vezu da biste opisali koji su to moduli.

Također, JVM interni (implementacijski) API-ji poput com.sun. * više nisu dostupni iz aplikacijskog koda.

Jednostavno rečeno, moduli će biti opisani u datoteci pod nazivom module-info.java nalazi se na vrhu hijerarhije Java koda:

modul com.baeldung.java9.modules.car {zahtijeva com.baeldung.java9.modules.engines; izvozi com.baeldung.java9.modules.car.handling; } 

Naš modul automobil zahtijeva modul motor za pokretanje i izvoz paketa za rukovanje.

Za detaljniji primjer provjerite OpenJDK Jigsaw projekta: Vodič za brzi početak sustava modula.

3. Novi HTTP klijent

Dugo očekivana zamjena starog HttpURLConnection.

Novi API nalazi se pod java.net.http paket.

Trebao bi podržavati HTTP / 2 protokol i WebSocket rukovanje, s performansama koje bi trebale biti usporedive s Apache HttpClient, Netty i Jetty.

Pogledajmo ovu novu funkcionalnost stvaranjem i slanjem jednostavnog HTTP zahtjeva.

Ažuriranje: HTTP klijent JEP premješta se u modul Inkubator, tako da više nije dostupan u paketu java.net.http i umjesto toga je dostupan pod jdk.inkubator.http.

3.1. Brzi GET zahtjev

API koristi obrazac Builder, što ga čini vrlo jednostavnim za brzu upotrebu:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .GET () .build (); HttpResponse odgovor = HttpClient.newHttpClient () .send (zahtjev, HttpResponse.BodyHandler.asString ()); 

4. API procesa

API procesa je poboljšan za kontrolu i upravljanje procesima operativnog sustava.

4.1. Obraditi informacije

Razred java.lang.ProcessHandle sadrži većinu novih funkcionalnosti:

ProcessHandle self = ProcessHandle.current (); dugo PID = self.getPid (); ProcessHandle.Info procInfo = self.info (); Izborni args = procInfo.arguments (); Neobvezno cmd = procInfo.commandLine (); Po izboru startTime = procInfo.startInstant (); Neobvezno cpuUsage = procInfo.totalCpuDuration ();

The Trenutno metoda vraća objekt koji predstavlja proces koji trenutno radi JVM. The Informacije potklasa pruža detalje o procesu.

4.2. Uništavajući procesi

Sada - zaustavimo sve pokrenute podređene procese koji se koriste uništiti():

childProc = ProcessHandle.current (). children (); childProc.forEach (procHandle -> {assertTrue ("Ne mogu ubiti proces" + procHandle.getPid (), procHandle.destroy ());});

5. Male jezične izmjene

5.1. Pokušajte s resursima

U Javi 7, pokušajte s resursima sintaksa zahtijeva deklariranje nove varijable za svaki resurs kojim se upravlja izjavom.

U Javi 9 postoji dodatno usavršavanje: ako se na resurs referencira konačna ili efektivna konačna varijabla, naredba try-with-resources može upravljati resursom bez deklariranja nove varijable:

MyAutoCloseable mac = novo MyAutoCloseable (); try (mac) {// učiniti neke stvari s mac} try (new MyAutoCloseable () {} .finalWrapper.finalCloseable) {// učiniti neke stvari s finalCloseable} catch (Iznimka ex) {} 

5.2. Proširenje dijamantskog operatora

Sada dijamantski operator možemo koristiti zajedno s anonimnim unutarnjim klasama:

FooClass fc = novi FooClass (1) {// anonimna unutarnja klasa}; FooClass fc0 = novi FooClass (1) {// anonimni unutarnji razred}; FooClass fc1 = novi FooClass (1) {// anonimni unutarnji razred}; 

5.3. Privatna metoda sučelja

Sučelja u nadolazećoj JVM verziji mogu imati privatni metode, koje se mogu koristiti za razdvajanje podužih zadanih metoda:

sučelje InterfaceWithPrivateMethods {private static String staticPrivate () {return "static private"; } private String instancePrivate () {return "instance private"; } zadana provjera void () {Rezultat niza = staticPrivate (); InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods () {// anonimna klasa}; rezultat = pvt.instancePrivate (); }}}

6. Alat za naredbene retke JShell

JShell je čitava – eval – ispisna petlja - skraćeno REPL.

Jednostavno rečeno, to je interaktivni alat za procjenu deklaracija, izjava i izraza Java, zajedno s API-jem. Vrlo je prikladan za testiranje malih isječaka koda, koji inače zahtijevaju stvaranje nove klase s glavni metoda.

The jshell sam izvršni program se može naći u / kanta za smeće mapa:

jdk-9 \ bin> jshell.exe | Dobrodošli u JShell - Verzija 9 | Za uvodni tip: / help intro jshell> "Ovo je moj dugački niz. Želim njegov dio" .substring (8,19); $ 5 ==> "moj dugi niz"

Interaktivna ljuska dolazi s poviješću i automatskim dovršavanjem; također pruža funkcionalnost poput spremanja i učitavanja iz datoteka, svih ili nekih napisanih izjava:

jshell> / spremi c: \ razvijaj \ JShell_hello_world.txt jshell> / otvori c: \ razvijaj \ JShell_hello_world.txt Pozdrav JShell! 

Isječci koda izvršavaju se nakon učitavanja datoteke.

7. Podnaredbe JCMD

Istražimo neke od novih naredbi u jcmd uslužni program naredbenog retka. Dobit ćemo popis svih klasa učitanih u JVM i njihovu strukturu nasljeđivanja.

U donjem primjeru možemo vidjeti hijerarhiju java.lang.Socket učitana u JVM koji pokreće Eclipse Neon:

jdk-9 \ bin> jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 14056: java.lang.Object / null | --java.net.Socket / null | implementira java.io.Closeable / null (proglašen intf) | implementira java.lang.AutoCloseable / null (naslijeđen intf) | | --org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket | | implementira java.lang.AutoCloseable / null (naslijeđen intf) | | implementira java.io.Closeable / null (naslijeđen intf) | | --javax.net.ssl.SSLSocket / null | | implementira java.lang.AutoCloseable / null (naslijeđen intf) | | implementira java.io.Closeable / null (naslijeđen intf) 

Prvi parametar jcmd naredba je ID procesa (PID) JVM-a na kojem želimo pokrenuti naredbu.

Još je jedna zanimljiva naredba set_vmflag. Neke JVM parametre možemo mijenjati na mreži, bez potrebe za ponovnim pokretanjem JVM procesa i izmjenom njegovih parametara pokretanja.

Možete pronaći sve dostupne VM zastavice s podnaredbom jcmd 14056 VM.znaci -sve

8. API za višestruku razlučivost slike

Sučelje java.awt.image.MultiResolutionImage enkapsulira skup slika različitih razlučivosti u jedan objekt. Možemo dohvatiti varijantu slike specifične za rezoluciju na temelju zadane DPI metrike i skupa transformacija slike ili dohvatiti sve varijante na slici.

The java.awt.Grafika klasa dobiva varijantu sa slike s više rezolucija na temelju trenutne DPI metrike zaslona i svih primijenjenih transformacija.

Razred java.awt.image.BaseMultiResolutionImage pruža osnovnu implementaciju:

BufferedImage [] резолюціяVariants = .... MultiResolutionImage bmrImage = nova BaseMultiResolutionImage (baseIndex, resolutionVariants); Slika testRVImage = bmrImage.getResolutionVariant (16, 16); assertSame ("Slike bi trebale biti iste", testRVImage, resolutionVariants [3]); 

9. Promjenjive ručke

API se nalazi pod java.lang.poziv a sastoji se od VarHandle i MetodaRuke. Pruža ekvivalente java.util.concurrent.atomic i sunce.misc.Nesigurno operacije nad objektnim poljima i elementima niza sa sličnim izvedbama.

Uz Java 9 modularni pristup sustavu sunce.misc.Nesigurno neće biti moguće iz aplikacijskog koda.

10. Okvir za objavljivanje i pretplatu

Razred java.util.concurrent.Flow pruža sučelja koja podržavaju okvir za objavljivanje i pretplatu reaktivnog toka. Ova sučelja podržavaju interoperabilnost kroz brojne asinkrone sustave koji se izvode na JVM-ovima.

Možemo koristiti klasu korisnosti SubmissionPublisher za stvaranje prilagođenih komponenata.

11. Objedinjeno JVM bilježenje

Ova značajka uvodi zajednički sustav bilježenja za sve komponente JVM-a. Pruža infrastrukturu za bilježenje, ali ne dodaje stvarne pozive za bilježenje iz svih JVM komponenata. Također ne dodaje bilježenje Java koda u JDK.

Okvir zapisivanja definira skup oznake - na primjer, gc, sastavljač, nitiitd. Možemo koristiti parametar naredbenog retka -Xlog za uključivanje zapisivanja tijekom pokretanja.

Zabilježimo poruke označene oznakom 'gc' pomoću razine 'otklanjanja pogrešaka' u datoteku zvanu 'gc.txt' bez ukrasa:

java -Xlog: gc = otklanjanje pogrešaka: datoteka = gc.txt: nema ...

-Xlog: pomoć prikazat će moguće opcije i primjere. Konfiguracija evidentiranja može se izmijeniti tijekom izvođenja pomoću jcmd naredba. Postavit ćemo GC zapisnike na informacije i preusmjeriti ih u datoteku - gc_logs:

jcmd 9615 VM.log output = gc_logs what = gc

12. Novi API-ji

12.1. Nepromjenjivi set

java.util.Set.of () - stvara nepromjenjivi skup zadanih elemenata. U Javi 8 za stvaranje niza od nekoliko elemenata bilo bi potrebno nekoliko redaka koda. Sada to možemo učiniti jednostavno:

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

The Postavi vraćen ovom metodom je JVM interna klasa: java.util.ImmutableCollections.SetN, koji se proširuje na javnost java.util.AbstractSet. Nepromjenjiv je - ako pokušamo dodati ili ukloniti elemente, an UnsupportedOperationException bit će bačen.

Također možete pretvoriti cijeli niz u Postavi istom metodom.

12.2. Nije obavezno za Stream

java.util.Optional.stream () daje nam jednostavan način da iskoristite snagu streamova na neobaveznim elementima:

Popis filteredList = listOfOptionals.stream () .flatMap (Neobvezno :: stream) .collect (Collectors.toList ()); 

13. Zaključak

Java 9 dolazi s modularnim JVM-om i mnoštvom novih i raznolikih poboljšanja i značajki.

Izvorni kod za primjere možete pronaći na GitHubu.