Kategorie
java

Java 15 – co nowego w JDK?

Java 14 już za nami. Java JDK 15 to kolejny przystanek na drodze rozwoju języka. Text Blocks, Hidden Classes, garbage collectory ZGC i Shenandoah, to tylko kilka z ciekawszych zmian. Szczegóły w artykule.

Będę aktualizował dla Was artykuł, gdy będą się pojawiać nowe wiadomości. Co nowego czeka nas zatem w Java 15?

Aktualizacja 2020-05-14 2020-05-20 2020-05-26

Harmonogram wydania

Kolejne, już 15, wydanie Javy przebiega już wg znanego procesu JDK Release Process. 11 czerwca zostanie osiągnięty milestone Rampdown Phase One i będziemy znali pełen zamrożony zbiór funkcjonalności dotyczących najbliższej wersji.

Finalne wydanie zaplanowane jest na 15 września.

Poniżej cały harmonogram.

2020/06/11 Rampdown Phase One (fork from main line)
2020/07/16 Rampdown Phase Two
2020/08/06 Initial Release Candidate
2020/08/20 Final Release Candidate
2020/09/15 General Availability

Co wchodzi do Java JDK 15?

Lista JEP (ang. JDK Enhancement Proposal), czyli propozycji rozszerzeń do JDK jest w przypadku Java 15 dosyć krótka. Prezentuje się następująco:

339: Edwards-Curve Digital Signature Algorithm (EdDSA) (aktualizacja 2020-05-20)
360: Sealed Classes (Preview) (aktualizacja 2020-05-26)
371: Hidden Classes
372: Remove the Nashorn JavaScript Engine
373: Reimplement the Legacy DatagramSocket API
374: Disable and Deprecate Biased Locking
375: Pattern Matching for instanceof (Second Preview)
377: ZGC: A Scalable Low-Latency Garbage Collector
378: Text Blocks
379: Shenandoah: A Low-Pause-Time Garbage Collector
381: Remove the Solaris and SPARC Ports (aktualizacja 2020-05-26)
383: Foreign-Memory Access API (Second Incubator) (aktualizacja 2020-05-26)
384: Records (Second Preview) (aktualizacja 2020-05-20)

Przyjrzyjmy się teraz bliżej, co z czym się je.

339: Edwards-Curve Digital Signature Algorithm (EdDSA)

Zmiana ta wprowadza do Java JDK 15 schematy podpisów cyfrowych opartych o krzywą eliptyczną Edwardsa. Algorytm można przejrzeć w RFC8032. Z pewnością wpłynie to na zwiększenie możliwości bezpieczeństwa Java 15.

360: Sealed Classes (Preview)

Ciekawa zmiana umożliwiająca klasie lub interfejsowi typu sealed na zdefiniowanie, które klasy lub interfejsy będą mogły je rozszerzać lub implementować. Wynika z tego, że programista będzie miał większą kontrolę nad kodem. Sam kod ma być w tym obszarze bardziej deklaratywny. Przykłady:

package com.example.geometry;

public sealed class Shape
    permits Circle, Rectangle, Square {...}

Mamy zatem dwa nowe keywords, tj. sealed i permits.

Idąc dalej przy ograniczeniu typów nasuwa się skojarzenie z Case Classes ze Scali. I w tym przypadku to skojarzenie jest jak najbardziej trafne. Moc tej zmiany powinniśmy zobaczyć zatem w powiązaniu z 375: Pattern Matching for instanceof (Second Preview), gdzie kompilator będzie automatycznie w stanie określić, wyczerpanie opcji w switch. A zatem brak konieczności definiowania default i automatyczne wykrycie, gdyby pojawiła się w bloku klasa spoza dopuszczalnego zakresu. Przykład poniżej.

Shape rotate(Shape shape, double angle) {
    return switch (shape) {
        case Circle c    -> c;  // no action needed
        case Rectangle r -> r.rotate(angle);
        case Square s    -> s.rotate(angle);
    }
}

Podsumowując, mamy szansę na bezpieczniejszy kod.

371: Hidden Classes

Hidden Classes … czy właściwie co? Okazuje się, że głównie na potrzeby różnych frameworków korzystne jest wprowadzenie typu klas, które nie będą mogły być użyte bezpośrednio przez bytecode innych klas. Brzmi lekko tajemniczo?

Krótkie wytłumaczenie. Dużo frameworków tworzy różne wewnętrzne klasy podczas runtime. Następnie są one wykorzystywane przez mechanizm refleksji.

Do tego wykorzystywane są standardowe mechanizmy zawarte w ClassLoader::defineClass iLookup::defineClass. Zauważono tutaj, że taki sposób generowania ze względu na to, że klasa taka jest widoczna dla innych klas w ramach hierarchii classloadera, ma dwie wady:

  • Klasa taka jest widoczna, a przez to mogą z niej próbować korzystać inne klasy.
  • Jej cykl życia wobec tego może być dłuższy niż powinien, czego efektem jest niezwalnianie pamięci.

Wprowadzenie Hidden Classes pozwoli na ukrycie wewnętrznych mechanizmów frameworków, również przed mechanizmem zewnętrznej refleksji.

Dzięki nowemu podejściu będzie możliwa agresywna optymalizacja polegająca na wyładowaniu takich klas z pamięci, a przez to jej większa dostępność dla innych elementów systemu. Normalnie nie byłoby to możliwe aż do czasu zakończenia cyklu życia classloadera. W tym przypadku to nie classloader będzie odpowiadał za wczytanie Hidden Class, a zatem wyładowanie jej z pamięci nie będzie miało tego ograniczenia.

Docelowo zmiana ma nie wpływać na język Java jako taki. Ale widać, że trochę rozwiązań będzie musiało się do niej dostosować wewnętrznie, np. GraalVM, z którym dobrze współpracuje Quarkus, o którym było już na blogu tutaj.

372: Remove the Nashorn JavaScript Engine

Nashorn, który pojawił się jeszcze w JDK 8, kończy swój udział w Javie. Moim zdaniem to bardzo dobrze, bo nie do końca sensowne było w ogóle jego wprowadzanie.

Javascript rozwija się bardzo dynamicznie, a co za tym idzie trzymanie silnika tego typu wewnątrz JDK, nie ma obecnie za wiele sensu.

Wydaje się, że Oracle jest podobnego zdania i stawia tutaj zdecydowanie na GraalVM. Czyli nadal Javascript na JVM, ale niezależnie od samej Javy.

373: Reimplement the Legacy DatagramSocket API

Leciwe już API zostanie odświeżone. W tej zmianie zwrócono uwagę na to, że API zawiera dużo przestarzałego kodu Javy wymiksowanego z kodem w C. Jego źródła datowane są jeszcze na Javę 1.0.

Od czasu powstania tego kodu IPv6 stało się dostępnym normalnie standardem, którego zgranie z IPv4 było w tym kodzie trudne w utrzymaniu. Dodatkowe problemy wynikały z błędów w obsłudze asynchronicznych metod. Czyli czas na wprowadzenie większych ulepszeń.

374: Disable and Deprecate Biased Locking

Wprowadzone jako optymalizacja do maszyny wirtualnej Biased Locking uznano za większy problem niż się pierwotnie wydawało. Ze względu na złożoność kodu i koszty utrzymania postanowiono zrezygnować z tych funkcji.

375: Pattern Matching for instanceof (Second Preview)

Pierwsze Preview wprowadzone do JDK 14 było wg mnie dobrym posunięciem. Nowoczesne języki pokazują, że Pattern Matching jest bardzo pożytecznym mechanizmem. Pisałem o tym wcześniej, więc odsyłam do przykładu z artykułu Java 14 – co nowego?

377: ZGC: A Scalable Low-Latency Garbage Collector

ZGC, jako pierwszy z garbage collectorów wchodzący w wersji produkcyjnej do Java JDK 15, debiutuje w końcu również na Windows macOS.

Od JDK 11 mogliśmy korzystać z ZGC eksperymentalnie. Wygląda na to, że jest to już materiał wygrzany i można go z sukcesem wykorzystywać w rozwiązaniach produkcyjnych.

Jest to garbage collector nastawiony na niską latencję (ang. low-latency garbage collector). Oznacza to, że jest optymalizowany pod kątem krótkiego czasu odśmiecania pamięci.

Z ciekawostek – docelowo czas pauzy nie przekracza 10 ms, a ambicje projektantów dążą do pauzy krótszej od 1ms. Maksymalny heap size jest całkiem spory, bo wynosi 16 TB (terabajtów). Nie powinniście czuć się zatem nim przesadnie ograniczeni 😀

378: Text Blocks

Wprowadzenie wielowierszowych bloków tekstowych jest długo oczekiwanym rozwiązaniem przez wielu programistów.

Z pewnością unikniemy dzięki tej konstrukcji licznych sekwencji specjalnych (ang. escape sequence), a nasz kod będzie czytelniejszy.

Zilustrować można to rozwiązanie przykładem. Tradycyjne rozwiązanie:

String text = "line 1\nline 2\nline 3\n";

w nowej wersji będzie można uzyskać bardziej przejrzystym zapisem:

String text = """
              line 1
              line 2
              line 3
""";

Spacje poprzedzające tekst zostaną usunięte w czasie inteligentnej kompilacji. Zobaczymy, czy będzie to działać idealnie.

Być może doczekamy się za jakiś czas zmian związanych z interpolacją zmiennych w takich literałach. Na razie ich brak. Ale zmiana ta jest z pewnością godna uwagi.

379: Shenandoah: A Low-Pause-Time Garbage Collector

Drugi garbage collector w zestawieniu. I też bazujący na niskiej latencji. Młodszy brat ZGC dostaje zielone światło jako rozwiązanie produkcyjne.

381: Remove the Solaris and SPARC Ports

Przychodzi taki czas, że w każdym projekcie należy zastanowić się nad kodem, który już trochę się zdezaktualizował. W tym przypadku utrzymanie kodu było kosztowne i trudne. W efekcie blokowało rozwój kilku nowych zmian (np. Loom).

383: Foreign-Memory Access API (Second Incubator)

Zmiana to jest próbą wprowadzenia jednorodnego sposobu do dostępu do pamięci poza stertą. Stare API nie było najlepsze. Nowe ma stać się realną alternatywą dla cieszącego się niezbyt chlubną sławą sun.misc.Unsafe. Wydaje się, że w końcu sun.misc.Unsafe będzie mógł odejść na zasłużony odpoczynek.

384: Records (Second Preview)

Bardzo się cieszę z tej zmiany. Wprowadzenie drugiego Preview w JDK 15 daje szanse na to, że typy niezmiennicze zagoszczą na stałe w samym języku już w JDK 16. Ponieważ pisałem o tym już wcześniej, to zachęcam do przejrzenia artykułu Java 14 – co nowego?

Jakie zmiany czekały do końca na decyzję o wejściu do Java 15?

Zmiany, które były rozważane … i ostatecznie weszły do Java 15:

  • 339: Edwards-Curve Digital Signature Algorithm (EdDSA) 2020/05/14
    Wprowadzenie do JDK algorytmów podpisów cyfrowych opartych o krzywą Edwardsa. (Weszło do Java JDK 15, opis powyżej)
  • 360: Sealed Classes (Preview) 2020/05/20
    Klasa lub interfejs typu sealed będzie definiowała klasy lub interfejsu, które będą mogły ją rozszerzać lub implementować. (Weszło do Java JDK 15, opis powyżej)
  • 381: Remove the Solaris and SPARC Ports 2020/05/20
    Zmiany te mają na celu usunięcie specyficznego kodu dla tych platform. Ich utrzymanie i zachowanie kompatybilności wpływa na wolniejsze wdrażanie nowoczesnych elementów (m. in. Loom). (Weszło do Java JDK 15, opis powyżej)
  • 383: Foreign-Memory Access API (Second Incubator)
    Wprowadzenie do JDK możliwości bezpiecznego i efektywnego dostępu do pamięci poza stertą. Wprowadzenie nowego API ma na celu zapewnienie jednorodnego mechanizmu do dostępu do takiej pamięci. (propozycja dodana po 2020-05-14) (Weszło do Java JDK 15, opis powyżej)
  • 384: Records (Second Preview) 2020/05/14
    Records, czyli typy niezmiennicze. Osobiście mam nadzieję, że szybko wejdą do kolejnej produkcyjnej wersji. Szczegóły w Java 14 – co nowego? (Weszło do Java JDK 15, opis powyżej)

Podsumowanie Java 15

Na pierwszy rzut oka lista rozwiązań proponowanych do Java JDK 15 nie wydaje się szczególnie ciekawa. Ale, jak mówimy, diabeł tkwi w szczegółach. Kilka bardzo zaawansowanych modyfikacji, których nie widzimy na co dzień sprawia, że warto poczytać o szczegółach ich implementacji.

Od strony kodu nowe Text Blocks są fajnym rozwiązaniem i na pewno szybko zyskają rzesze zwolenników.

Jestem fanem pierwszego preview Records. Liczę, że również drugie preview zostanie wciągnięte do tej edycji.

Czy też uważasz, że nowe Text Blocks są fajne ❓

A przy okazji – czy czytałeś już Junior Java Developer Handbook ❓

junior-hava-developer-handbook-what-to-know

0 0 vote
Article Rating
Subscribe
Powiadom o
guest
0 komentarzy
Inline Feedbacks
View all comments