Java 10 is de snelste release van een Java-versie in zijn 23-jarige geschiedenis. Java is bekritiseerd vanwege zijn trage groei en evolutie, maar Java 10 heeft dat concept doorbroken. Java 10 is een release met veel futuristische veranderingen, waarvan de reikwijdte en impact misschien niet voor de hand liggen, maar verstrekkend zijn. In dit artikel zullen we de verschillende functies bespreken die zijn toegevoegd in de Java 10-release. Voordat we dat doen, laten we enkele wijzigingen doornemen die zijn geïntroduceerd in het Java-releasemodel.
Model voor langdurige ondersteuning
Sinds 2017 hebben Oracle & de Java-gemeenschap aangekondigd over te stappen naar een nieuwe cyclus van 6 maanden voor Java. Het ging over naar een model voor langdurige ondersteuning (LTS) voor Oracle Java SE-producten. Wat betekent dit? LTS-versies van de producten bieden eersteklas en blijvende ondersteuning van Oracle en worden elke 3 jaar uitgebracht. Elke Java-release is gemodelleerd naar één of twee belangrijke kenmerken; deze kenmerken sturen de release aan. Elk obstakel stelt de release uit en brengt deze laat op de markt. Project Jigsaw was een belangrijk kenmerk van Java 9, het stelde de releasedata een paar keer uit en de release werd meer dan 1,5 jaar vertraagd. Releases volgens een cyclus van 6 maanden zullen een ‘release train’ volgen. De release train heeft om de 6 maanden een schema. Functies die de selectie halen, worden op de trein gezet; anders wachten ze op de volgende geplande trein.
Oracle JDK vs OpenJDK
Om meer ontwikkelaarsvriendelijk te zijn, promoot Oracle samen met de Java-gemeenschap nu de OpenJDK-binaries als de primaire JDK voor de toekomst. Dit is een grote opluchting ten opzichte van vroeger, toen de JDK-binaries eigendom waren van Oracle en onder licentie vielen, met verschillende beperkingen rond distributie. Oracle blijft echter hun JDK produceren, maar alleen voor langdurige ondersteuningsuitgaven. Dit is een stap naar meer cloud- en container-vriendelijkheid, aangezien de open JDK-binaries kunnen worden gedistribueerd als onderdeel van een container. Wat betekent dit? OpenJDK-binaries zullen elke 6 maanden worden vrijgegeven, terwijl Oracle JDK-binaries elke 3 jaar (LTS-versie) worden vrijgegeven. Welke JDK-binaries zullen worden aangenomen? Grote organisaties hebben tijd nodig om tussen de versies over te stappen; ze blijven bij een versie totdat ze kunnen. De adoptie in de industrie voor Java 6 was groter dan voor Java 7 en vervolgens stapt de industrie geleidelijk over op Java 8. Naar mijn mening zullen de LTS-versies het meest worden gekozen door de bedrijven. Het is echter nog niet bekend of het de LTS-versie van Oracle JDK of OpenJDK zal zijn, mede omdat er veel gebeurt in de cloud-ruimte. Java 9 & 10 zijn niet-LTS-releases. Java 11, dat gepland staat voor september 2018, zal een LTS-release zijn.
Java 10 Functies
Laten we eens een voorproefje nemen van de functies die beschikbaar zijn in Java 10.
Met de invoering van het op tijd gebaseerde releasecyclus heeft Oracle het versie-stringschema van de Java SE-platform en de JDK, en gerelateerde versie-informatie, gewijzigd voor huidige en toekomstige op tijd gebaseerde release-modellen. Het nieuwe patroon van het versienummer is: $FEATURE.$INTERIM.$UPDATE.$PATCH
$FEATURE: de teller wordt elke 6 maanden verhoogd en is gebaseerd op functie-releaseversies, bijvoorbeeld: JDK 10, JDK 11. $INTERIM: de teller wordt verhoogd voor niet-functiereleases die compatibele bugfixes en verbeteringen bevatten, maar geen onverenigbare wijzigingen. Meestal zal dit nul zijn, omdat er geen tussenliggende release zal zijn in een periode van zes maanden. Dit wordt bewaard voor een toekomstige herziening van het release-model. $UPDATE: de teller wordt verhoogd voor compatibele update-releases die beveiligingsproblemen, regressies en bugs in nieuwere functies oplossen. Dit wordt bijgewerkt één maand na de functierelease en daarna elke 3 maanden. De release van april 2018 is JDK 10.0.1, de release van juli is JDK 10.0.2, enzovoort $PATCH: de teller wordt verhoogd voor een noodrelease om een kritiek probleem op te lossen. Nieuwe API’s zijn toegevoegd om deze tellerwaarden programmatisch op te halen. Laten we eens kijken;
Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();
Nu gaan we eens kijken naar de Java-launcher die de versie-informatie retourneert:
$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
Het versienummerformaat is “10” omdat er geen andere teller is dan nul. De releasedatum is toegevoegd. 18.3 kan worden gelezen als het jaar 2018 & 3e maand, build 10+46 is de 46e build voor versie 10. Voor een hypothetische build 93 van JDK 10.0.1, zal de build zijn 10.0.1+939. ### Lokale variabele type inference (JEP 286)
Lokale variabel type-inferentie is de grootste nieuwe functie in Java 10 voor ontwikkelaars. Het voegt type-inferentie toe aan declaraties van lokale variabelen met initialisatoren. Lokale type-inferentie kan alleen worden gebruikt in de volgende scenario’s:
- Beperkt tot lokale variabele met initializer
- Indexen van verbeterde for-lus of indexen
- Lokaal gedeclareerd in for-lus
Laten we eens kijken naar het gebruik ervan:
var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList
// Index van Enhanced For Loop
for (var number : numbers) {
System.out.println(number);
}
// Lokaal variabele gedeclareerd in een lus
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
U kunt er meer over lezen in onze exclusieve post over java 10 lokale variabele type-inferentie.
Deze functie maakt het mogelijk om de op Java gebaseerde JIT-compiler, Graal, als een experimentele JIT-compiler te gebruiken op het Linux/x64-platform. Dit is verreweg de meest futuristische toevoeging aan de Java 10-functielijst. Graal werd geïntroduceerd in Java 9. Het is een alternatief voor de JIT-compiler waar we aan gewend zijn. Het is een plug-in voor de JVM, wat betekent dat de JIT-compiler niet is gebonden aan de JVM en dynamisch kan worden ingevoegd en vervangen door een andere plug-in die JVMCI-compatibel is (Java-Level JVM Compiler Interface). Het brengt ook Ahead of Time (AOT) compilatie in de Java-wereld. Het ondersteunt ook interpretatie van polyglot-talen. “Een op Java gebaseerde Just in Time-compiler geschreven in Java om de Java-bytecode naar machinetaal te converteren.” Is het verwarrend? Als JVM in Java is geschreven, heb je dan niet een JVM nodig om de JVM uit te voeren? De JVM kan AOT worden gecompileerd en vervolgens kan de JIT-compiler worden gebruikt binnen de JVM voor het verbeteren van de prestaties via live code-optimalisatie. Graal is een volledige herimplementatie van de JIT-compiler in Java, helemaal opnieuw geschreven. De vorige JIT-compiler was geschreven in c++. Het wordt beschouwd als een van de laatste stadia van evolutie voor elke programmeertaal. Je kunt overschakelen naar Graal met de volgende JVM-parameters:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
Meer informatie over Graal is te vinden in de presentatie van Chris Seaton.16. ### Toepassing van Class-Data Sharing (JEP 310)
Deze functie helpt bij het verbeteren van de opstartvoetafdruk, breidt de bestaande Class-Data Sharing (“CDS”)-functie uit om toepassingsklassen in het gedeelde archief te plaatsen. JVM voert bij het starten enkele voorbereidende stappen uit, waarvan het laden van klassen in het geheugen er een is. Als er meerdere jars zijn met meerdere klassen, is de vertraging bij het eerste verzoek duidelijk zichtbaar. Dit wordt een probleem bij serverloze architectuur, waarbij de opstarttijd cruciaal is. Om de opstarttijd van de toepassing te verkorten, kan Application class-data sharing worden gebruikt. Het idee is om de voetafdruk te verkleinen door gemeenschappelijke klassenmetadata te delen over verschillende Java-processen. Dit kan worden bereikt door de volgende 3 stappen: Bepalen van de te archiveren klassen: Gebruik de java launcher om een lijst van bestanden te maken die moeten worden gearchiveerd, dit kan worden bereikt met de volgende parameters:
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
Het AppCDS-archief maken: Gebruik java launcher om het archief van de lijst van bestanden te maken die moeten worden gebruikt voor Application CDS, dit kan worden bereikt met de volgende parameters:
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
Het AppCDS-archief gebruiken: Gebruik Java launcher met de volgende parameters om Application CDS te gebruiken.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
G1 garbage collector werd standaard in JDK 9. De G1 Garbage Collector vermijdt elke volledige garbage collection, maar wanneer gelijktijdige threads voor verzameling niet snel genoeg het geheugen kunnen vrijmaken, heeft dit invloed op de gebruikerservaring. Deze wijziging verbetert de slechtste latentie van G1 door de volledige GC parallel te maken. Het mark-sweep-compact algoritme van de G1-collector wordt geparelliseerd als onderdeel van deze wijziging en zal worden geactiveerd wanneer gelijktijdige threads voor verzameling het geheugen niet snel genoeg kunnen vrijmaken. 25. ### Garbage-Collector Interface (JEP 304)
Deze JEP is een toekomstgerichte wijziging. Het verbetert de code-isolatie van verschillende garbage-collectors door een gemeenschappelijke Garbage Collector Interface te introduceren. Deze wijziging zorgt voor een betere modulariteit van de interne GC-code. Het zal in de toekomst helpen bij het toevoegen van nieuwe GC’s zonder de bestaande codebasis te wijzigen, en ook helpen bij het verwijderen of opschonen van de vorige GC. 26. ### Aanvullende Unicode Language-Tag Extensies (JEP 314)
Deze functie verbetert java.util.Locale en gerelateerde API’s om aanvullende Unicode-extensies van BCP 47 taaltags te implementeren. Vanaf Java SE 9 worden de ondersteunde BCP 47 U-taal-tag-extensies “ca” en “nu” genoemd. Deze JEP zal ondersteuning toevoegen voor de volgende aanvullende extensies:
- cu (valutatype)
- fw (eerste dag van de week)
- rg (regio overschrijven)
- tz (tijdzone)
Om deze extra extensies te ondersteunen, worden er wijzigingen aangebracht in verschillende API’s om informatie te verstrekken op basis van U of aanvullende extensies.
java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider
Om OpenJDK te bevorderen en het aantrekkelijker te maken voor gemeenschapsgebruikers, biedt deze functie een standaardset van root Certification Authority (CA)-certificaten in de JDK. Dit betekent ook dat zowel Oracle- als OpenJDK-binaries functioneel hetzelfde zullen zijn. Kritieke beveiligingscomponenten zoals TLS zullen standaard werken in toekomstige OpenJDK-builds.30. ### Thread-Local Handshakes (JEP 312)
Dit is een interne JVM-functie om de prestaties te verbeteren. Een handdrukoperatie is een terugroepactie die wordt uitgevoerd voor elke JavaThread terwijl die thread zich in een safepoint-toestand bevindt. De terugroepactie wordt uitgevoerd door de thread zelf of door de VM-thread terwijl de thread in een geblokkeerde toestand wordt gehouden. Deze functie biedt een manier om een terugroepactie uit te voeren op threads zonder een wereldwijde VM-safepoint uit te voeren. Maak het zowel mogelijk als goedkoop om individuele threads te stoppen en niet alleen alle threads of geen.31. ### Heap Allocation on Alternative Memory Devices (JEP 316)
Toepassingen zijn geheugenhongerig geworden, er is een toename van cloud-native toepassingen, in-memory databases, streaming toepassingen. Om aan deze diensten tegemoet te komen, zijn er verschillende geheugenarchitecturen beschikbaar. Deze functie verbetert de mogelijkheid van HotSpot VM om de Java-objectheap op een alternatief geheugentoestel toe te wijzen, zoals een NV-DIMM, gespecificeerd door de gebruiker. Deze JEP richt zich op alternatieve geheugentoestellen die dezelfde semantiek hebben als DRAM, inclusief de semantiek van atomaire bewerkingen, en daarom in plaats van DRAM voor de objectheap kunnen worden gebruikt zonder enige wijziging in de bestaande toepassingscode.
### Verwijder de Native-Header Generatietool – javah (JEP 313)
Dit is een opruimwijziging om de javah-tool uit JDK te verwijderen. De functionaliteit van de tool is toegevoegd aan javac
als onderdeel van JDK 8, wat de mogelijkheid biedt om native koptekstbestanden te schrijven tijdens de compilatie, waardoor javah
nutteloos wordt.
### Bundel het JDK-bos in een enkel repository (JEP 296)
In de loop der jaren zijn er verschillende Mercurial-repositories geweest voor de JDK-codebase. Verschillende repositories bieden weliswaar enkele voordelen, maar ze hadden ook verschillende operationele nadelen. Als onderdeel van deze wijziging worden talrijke repositories van het JDK-bos samengevoegd tot een enkel repository om de ontwikkeling te vereenvoudigen en te stroomlijnen.
### API-wijzigingen
Java 10 heeft API’s toegevoegd en verwijderd (Ja, het is geen typefout). Java 9 introduceerde verbeterde veroudering waarbij bepaalde API’s werden gemarkeerd om te worden verwijderd in toekomstige releases. Verwijderde API’s: Je kunt de verwijderde API’s vinden hier. Toegevoegde API’s: Er zijn 73 nieuwe API’s toegevoegd in Java 10. Je kunt de toegevoegde API’s vinden samen met een vergelijking hier. Laten we een paar toevoegingen doornemen:
- Interfaces List, Map & Set zijn toegevoegd met een statische copyOf(Collection)-methode. Deze retourneert een niet-wijzigbare List, Map of Set met de geleverde items. Voor een List zal de geretourneerde List geen wijzigingen weerspiegelen als de gegeven List vervolgens wordt gewijzigd.
- Optional & zijn primitieve varianten krijgen een methode orElseThrow(). Dit is precies hetzelfde als get(), echter de javadoc vermeldt dat dit een voorkeursalternatief is dan get().
- De klasse Collectors krijgt diverse methoden voor het verzamelen van niet-wijzigbare collecties (Set, List, Map).
List actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// Nieuwe API toegevoegd - Maakt een niet-wijzigbare List van een List.
List copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Zal een
// UnsupportedOperationException genereren. genereren.
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
String str = "";
Optional name = Optional.ofNullable(str);
// Nieuwe API toegevoegd - is de voorkeursoptie dan de get() methode.
name.orElseThrow(); // same as name.get()
// Nieuwe API toegevoegd - Collectors.toUnmodifiableList.
List collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Zal een
// UnsupportedOperationException genereren. genereren.
Conclusie
In dit artikel hebben we de verschillende nieuwe functietoevoegingen van Java 10 doorgenomen. Als u denkt dat er hier iets belangrijks is overgeslagen, laat het ons dan weten via opmerkingen. Zoals gewoonlijk kunt u de volledige code controleren op GitHub hier.
Source:
https://www.digitalocean.com/community/tutorials/java-10-features