Java 18 ujrzała światło dzienne i według producenta ma nieść za sobą tysiące ulepszeń w zakresie wydajności, stabilności i bezpieczeństwa, które jeszcze bardziej zwiększą produktywność programistów.
„Wydanie Java 18 jest dowodem na to, że firma Oracle nieustannie dąży do zapewnienia przedsiębiorstwom i programistom szybszego dostępu do ulepszeń dzięki sześciomiesięcznemu cyklowi wydawania nowych wersji” — stwierdził Georges Saab, wiceprezes ds. rozwoju Java Platform w firmie Oracle.
Najnowszy pakiet Java Development Kit (JDK) zapewnia aktualizacje i ulepszenia dzięki dziewięciu rozszerzeniom (JDK Enhancement Proposals, JEP), a w tym wpisie pokrótce je omówimy 🙂
Spis treści
- 1 Kilka słów o wydawaniu nowych wersji
- 2 Lista zmian
- 2.1 JEP 400: UTF-8 by Default – domyślnie włączone wsparcie dla kodowania UTF-8
- 2.2 JEP 408: Simple Web Server – prosty serwer webowy
- 2.3 JEP 413: Code Snippets in Java API Documentation – fragmenty kodu w dokumentacji
- 2.4 JEP 416: Reimplement Core Reflection with Method Handles – reimplementacja Core Reflection API z użyciem MethodHandle
- 2.5 JEP 417: Vector API (Third Incubator) – trzeci inkubator
- 2.6 JEP 418: Internet-Address Resolution SPI
- 2.7 JEP 419: Foreign Function & Memory API (Second Incubator) – drugi inkubator
- 2.8 JEP 420: Pattern Matching for switch (Second Preview)
- 2.9 JEP 421: Deprecate Finalization for Removal
- 3 Dodatkowe materiały
- 4 20+ BONUSOWYCH materiałów z programowania
Kilka słów o wydawaniu nowych wersji
22 marca 2022 została wydana nowa wersja Java typu 'General-Availability Release’ – czyli bez przedłużonego okresu wsparcia.
Obecnie obowiązujące wydanie z przedłużonym wsparciem – Long Term Support (w skrócie LTS) to wersja Java 17 wydana we wrześniu 2021 z zadeklarowanym wsparciem przez minimum 8 lat.
Zgodnie z założeniami nowe wersje niebędące LTS mają być publikowane co pół roku, natomiast LTS co około 3 lata.
Obecnie tak to wygląda:
- Java SE 15 wrzesień 2020
- Java SE 16 marzec 2021
- Java SE 17 (LTS) wrzesień 2021
Planowane:
- Java SE 19 wrzesień 2022
- Java SE 20 marzec 2023
- Java SE 21 (LTS) wrzesień 2023
Przyjrzymy się teraz zmianom, które przynosi Java 18 🙂
Lista zmian
JEP 400: UTF-8 by Default – domyślnie włączone wsparcie dla kodowania UTF-8
Różne formaty kodowania niewątpliwie przysparzają deweloperom wielu problemów.
W kodzie bardzo często polega się na domyślnym kodowaniu, które pobierane jest z systemu operacyjnego – wtedy wystarczy, że zakodujemy dane u nas lokalnie z innym domyślnym kodowaniem i wyślemy je na serwer z innym domyślnym kodowaniem i problem gotowy.
Większość metod z JDK pozwala nam nadpisać wykorzystywane kodowanie – tutaj chodzi jednak o zmniejszenie prawdopodobieństwa błędu wynikającego z wykorzystania domyślnych wartości.
Dzięki tej zmianie deweloperzy mogą stosować UTF-8 jako domyślny zestaw znaków dla standardowych API Javy.
System.out.println(Charset.defaultCharset());
ZOBACZ
: ASCII – ASCII table, tablica kodów AsCii
JEP 408: Simple Web Server – prosty serwer webowy
Jest to narzędzie wiersza poleceń i API do uruchamiania uproszczonego serwera WWW, ale bez plików dynamicznych. Oferuje gotowy do użycia statyczny serwer plików HTTP z łatwą konfiguracją i minimalną funkcjonalnością.
Idea jest stosunkowo prosta – skoro już korzystamy ze środowiska Javowego i chcemy coś na szybko pokazać – to, zamiast instalować w tym celu niezależny serwer, możemy skorzystać z tego dostarczonego z JDK.
var server = SimpleFileServer.createFileServer( new InetSocketAddress(8008), Path.of("/home/tw/workspace/java18"), SimpleFileServer.OutputLevel.VERBOSE ); server.start();
tw@tw:~/workspace/java18$ nano index.html tw@tw:~/workspace/java18$ ~/.jdks/openjdk-18/bin/jwebserver
JEP 413: Code Snippets in Java API Documentation – fragmenty kodu w dokumentacji
To narzędzie wprowadza znacznik @snippet do standardowej dokumentacji JavaDoc, aby uprościć umieszczanie w dokumentacji API przykładowego kodu źródłowego.
Dotąd, aby dodać niewielki fragment kodu, konieczne było używanie tagów <pre>.
~/.jdks/openjdk-18/bin/javadoc -d doc -cp src/main/java --snippet-path ~/workspace/StormJava/java18/snippet-files pl.stormit.java18
ZOBACZ
: Komentarze i samodokumentujący się kod | Kurs Java
JEP 416: Reimplement Core Reflection with Method Handles
– reimplementacja Core Reflection API z użyciem MethodHandle
Ta aktualizacja zmniejszy koszty utrzymania i rozwoju zarówno interfejsów API java.lang.reflect jak i java.lang.invoke poprzez wprowadzenie obsługi metod jako podstawowego mechanizm odzwierciedlania.
JEP 417: Vector API (Third Incubator) – trzeci inkubator
Trzeci inkubator dostarcza API dla programistów, co pozwala lepiej wykorzystywać architekturę procesorów CPU – Vector API zapewniając skalowalne rozszerzenia wektorowe.
Do uruchomienia kodu niezbędne jest dodanie modułu: jdk.incubator.vector
--add-modules jdk.incubator.vector
public class VectorsExample { static final VectorSpecies<Double> SPECIES = DoubleVector.SPECIES_PREFERRED; static double[] A = IntStream.range(1, 512).mapToDouble(i -> i).toArray(); static double[] B = IntStream.range(1, 512).mapToDouble(i -> i).toArray(); public static void main(String[] args) throws Exception { Options opt = new OptionsBuilder() .include(VectorsExample.class.getSimpleName()) .forks(1) .warmupIterations(1) .measurementIterations(1) .build(); new Runner(opt).run(); } @Benchmark public void scalar(Blackhole blackhole) { double[] C = new double[512]; scalarComputation(A, B, C); blackhole.consume(C); } @Benchmark public void vector(Blackhole blackhole) { double[] C = new double[512]; vectorComputation(A, B, C); blackhole.consume(C); } void scalarComputation(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f; } } void vectorComputation(double[] a, double[] b, double[] c) { int i = 0; int upperBound = SPECIES.loopBound(a.length); for (; i < upperBound; i += SPECIES.length()) { // FloatVector va, vb, vc; var va = DoubleVector.fromArray(SPECIES, a, i); var vb = DoubleVector.fromArray(SPECIES, b, i); var vc = va.mul(va) .add(vb.mul(vb)) .neg(); vc.intoArray(c, i); } for (; i < a.length; i++) { c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f; } } }
ZOBACZ
: Benchmark sposobem na wydajniejsze aplikacje – JMH
JEP 418: Internet-Address Resolution SPI
JEP 418 – definiuje interfejs dostawcy usług (SPI) do rozpoznawania nazw hostów i adresów, aby java.net.InetAddress mógł korzystać z innych rozwiązań niż wbudowany w platformę mechanizm rozpoznawania nazw.
Interfejs API java.net.InetAddress zamienia nazwy hostów na adresy protokołu internetowego (IP) i odwrotnie.
Obecnie interfejs API korzysta z natywnego mechanizmu rozpoznawania systemu operacyjnego, który zazwyczaj jest skonfigurowany do korzystania z połączenia lokalnego pliku hosts i systemu nazw domen (DNS).
JEP 419: Foreign Function & Memory API (Second Incubator) – drugi inkubator
Wprowadza interfejs API, dzięki któremu programy Java mogą współdziałać z kodem i danymi poza środowiskiem wykonawczym Java. Dzięki wydajnemu wywoływaniu funkcji obcych (tj. kodu poza maszyną JVM) i bezpiecznemu dostępowi do pamięci obcej (tj. pamięci niezarządzanej przez maszynę JVM), interfejs API umożliwia programom Java wywoływanie natywnych bibliotek i przetwarzanie natywnych danych.
JEP 420: Pattern Matching for switch (Second Preview)
To rozwiązanie ulepsza język programowania Java dzięki dopasowywaniu wzorców dla wyrażeń i instrukcji przełącznika, a także rozszerzeń języka wzorców. Rozszerzenie dopasowania do wzorca w celu przełączenia umożliwia testowanie wyrażenia pod kątem wielu wzorców, z których każdy ma określone działanie, dzięki czemu złożone zapytania zorientowane na dane mogą być wyrażane zwięźle i bezpiecznie. Jest to funkcja języka w wersji zapoznawczej w JDK 18.
switch (input) { case null -> System.out.println("NULL"); case "a", "b" -> System.out.println("a-b"); default -> System.out.println("Default"); }
switch (input) { case Integer i && i>10 -> System.out.println("Integer > 10"); case Integer i -> System.out.println("Integer "+i); case Double d -> System.out.println("Double "+d); default -> System.out.println("Default"); }
ZOBACZ
: Java Switch Case | Kurs Java
JEP 421: Deprecate Finalization for Removal
Finalizacja pozostaje na razie domyślnie włączona, ale można ją wyłączyć, aby ułatwić wczesne testowanie. W przyszłej wersji zostanie domyślnie wyłączona, a w późniejszej wersji zostanie usunięta. Opiekunowie bibliotek i aplikacji, które opierają się na finalizacji, powinni rozważyć migrację do innych technik zarządzania zasobami, takich jak instrukcja try-with-resources i narzędzia czyszczące.
Dodatkowe materiały
20+ BONUSOWYCH materiałów z programowania
e-book – „8 rzeczy, które musisz wiedzieć, żeby dostać pracę jako programista”,
e-book – „Java Cheat Sheet”,
checklista – „Pytania rekrutacyjne”
i wiele, wiele wiecej!