Koniec roku się zbliża, czas wielkich podsumowań, ale również patrzenia w przyszłość. Dlatego też w ostatniej w tym roku edycji JVMowego Wtorku (tak, robimy sobie na tydzień przerwę świąteczną z kolejnymi edycjami) mamy dla Was przegląd nowości, które przyjdą wraz z JDK 18.
JDK 18 znalazła się początkiem grudnia w fazie “Rampdown”. Jest to javowa nomenklatura na popularny w wielu projektach przedwdrożeniowy “feature freeze” – w JDK nie pojawią się już żadne zaskakujące zmiany, twórcy skupią się obecnie wyłącznie na poprawie bugów. Dla nas oznacza to zaś ostateczną listę wszystkich featurów, które do JDK trafią. Dlatego też dzisiaj, trochę nietypowo, znowu edycja specjalna – kompilująca wszystko, co trafi do nas wraz z JDK 18.
Nowe funkcjonalności
413: Code Snippets in Java API Documentation
Zacznijmy od nowości, które mają największe prawdopodobieństwo bycia użytymi przez “przemysłowego” programistę. Jeżeli w tej sekcji spodziewaliście się jednak jakiegoś nowego syntaxu języka możecie się nieco rozczarować. Nowości dostarczane z nową edycją Javy są mocno hmmm… specjalistyczne.
Specjalistyczne, bo raczej nie spodziewam się, że zapowiedź wbudowania w Javę minimalistycznego Web Server wywróci sposób w jaki programujemy. Narzędzie ma być przydatne do tworzenia prototypów, i ad hocowego kodowania oraz testowania, zwłaszcza w kontekście edukacyjnym – i o ile rozumiem w jakiś sposób jego wprowadzenie, to naprawdę nie potrafię się nim jakoś “jarać”.
Narzędzie uruchamiane ma być z wiersza polecenia i potrafić serwować statyczne pliki w bieżącym katalogu komendą java -m jdk.httpserver. Wersja CLI posiadać będzie podstawowe opcje konfiguracyjne, jak wybór portu czy adresu do zbindowania. Dla tych, którzy chcą trochę bardziej pokonfigurować swoje rozwiązanie, dostępna będzie też możliwość odpalenia całości z poziomu kodu javowego.
Druga zmiana jest ciekawsza, aczkolwiek znając miłość branży do pisania dokumentacji, ponownie dotknie tylko wybranych programistów JEP 413 wprowadza znacznik @snippet do JavaDoc, co ma na celu uprościć dołączanie przykładowego kodu źródłowego do dokumentacji API.
Do tej pory dokumentacja nie posiadała specjalnego tagu pozwalającego programistom przekazać przykładowe użycia API. Teraz to się zmieni. Co ciekawe, twórcy API zapewnili użytkownikom dwa różne warianty. Przykłady będzie można przekazać “inline”:
/**
* The following code shows how to use {@code Optional.isPresent}:
* {@snippet :
* if (v.isPresent()) {
* System.out.println("v: " + v.get());
* }
* }
*/
Ale również jako zewnętrzny plik:
/**
* The following code shows how to use {@code Optional.isPresent}:
* {@snippet file="ShowOptional.java" region="example"}
*/
---------------------------
public class ShowOptional {
void show(Optional<String> v) {
// @start region="example"
if (v.isPresent()) {
System.out.println("v: " + v.get());
}
// @end
}
}
Zainstaluj teraz i czytaj tylko dobre teksty!
Zmiany pod maską
416: Reimplement Core Reflection with Method Handles
418: Internet-Address Resolution SPI
Jeżeli chodzi o dodatki z kategorii #nikogo, JEP 416 – Reimplement Core Reflection with Method Handles zdecydowanie należy do moich ulubionych. JEP ten przynosi bowiem unifikacje sposobu, w jaki działa refleksja w Javie. W jego ramach dochodzi do reimplementacji java.lang.reflect.Method, java.lang.reflect.Constructor, i java.lang.reflect.Field na mechanizm invoke, wprowadzony w JDK 1.7. Jest to rodzaj spłaty długu technicznego przez zespół pracujący nad językiem i maszyną wirtualną, jako użytkownicy nie zauważymy więc jakichś znaczących zmian. JEP 416 jest jednak w zasadzie niezbędny do wprowadznia zmian w architektórze JVMa, które przyjdą wraz z projektem Loom i Valhalla.
Następnym jest JEP o bardzo ładnym, okrągłym numerze 400, który wprowadza wreszcie UTF-8 do Javy domyślny sposób kodowania znaków. Choć historycznie było z tym różnie obecnie żyjemy w świecie w którym enkodowanie znaków wydaje się być rozwiązanym problemem. Globalizacja (i po części też rozwój hardware) sprawiły, że zamiast wielu lokalnych standardów mamy obecnie jeden – Unicode Transformation Format, czyli popularny UTF, potrafiący reprezentować znaki z wszystkich języków i dialektów, a dodatkowo wiele więcej, jak kochane przez wszystkich emoji. W związku z faktem, że wiele języków programowania postanowiło już dawno uczynić go rozwiązaniem domyślnym, na podobny krok zdecydowała się również Java.
O ile dla stałych czytelników większość z powyższych opisywanych zmian nie będzie niczym nowym, tak jako ostatni przedstawimy Wam JEP, który umknął naszej uwadze, a jest dość ciekawy. java.net.INetAddress to API służące do rozwiązywania nazwy hostów na adresy IP (i odwrotnie). Interfejs API obecnie korzysta z natywnego rozwiązywania DNSów dostarczanego przez systemy operacyjne. Takowe w większości przypadków operuje na lokalnym pliku hosts i zewnętrznych DNS-ach. Są to rozwiązania synchroniczne, w związku z tym na potrzeby prac nad projektem Loom musza pojawić się w JVMie alternatywy. Dlatego też w ramach prac nad JEP-418 interfejs INetAddress ma być oddzielony od implementacji, co umożliwi stworzenie odpowiednich alternatyw działających w sposób nieblokujący
Lektura nadprogramowa:
Inkubator
417: Vector API (Third Incubator)
419: Foreign Function & Memory API (Second Incubator)
420: Pattern Matching for switch (Second Preview)
Tutaj nie będę się długo rozgadywał – każde z powyższych API już choć raz w inkubatorze było, a zmiany w nich są na tyle kosmetyczne, że myślę że z czystym sumieniem mogę Was odesłać do oryginalnych dokumentów.
Powiedzmy sobie prawdę – ludzie używający funkcjonalności w preview pewnie i tak już dawno się z powyższymi JEPami zapoznali. Dla reszty niech wystarczy fakt, że Vector API oraz Foreign Function & Memory API przynoszą usprawnienia kompatybilności z kodem natywnym, a Pattern Matching for switch to nic innego jak dalsze wprowadzanie kawałek po kawałku Pattern Matchingu do Javy.
A co wylatuje?
JEP 421: Deprecate Finalization for Removal
To może tak na koniec JEP 421: Deprecate Finalization for Removal – czyli deprekacja mechanizmu finalizatorów. Dla tych, którzy z finalizatorami nigdy nie mieli do czynienia, mówimy o formie hooka/aspektu, odpalanego bezpośrednio przed zniszczeniami obiektu przez garbage collector. To, co w teorii brzmi jak dość przydatna możliwość, w praktyce było funkcją mocno nieprzewidywalną (istniał szereg sytuacji, gdzie finalizer z różnych powodów nie był odpalany) i dlatego również bardzo rzadko używaną.
Dodatkowo, JDK 1.7 wprowadził dużo lepiej zaprojektowany mechanizm try-with-resources, który zastąpił finalizacje w najpopularniejszych przypadkach użycia, takich jak np. zamykanie połączeń do pliku. Dlatego pozostaje przy twierdzeniu, że dla większości ludzi usunięcie finalizatorów pozostaje ciekawostką, podobną do sytuacji z Security Managerem. Jeśli jednak jesteście ciekaw, jakie są alternatywy – polecam oryginalny JEPem albo piętnasty odcinek Inside Java Newscast od Oracle, który znajdziecie poniżej.
Lektura nadprogramowa
Zainstaluj teraz i czytaj tylko dobre teksty!
Podsumowanie
Poprzednie wydanie Javy, JDK 17, było LTSem o wydłużonym przyszłym wsparciu. Dlatego też można się było spodziewać, że wszelkie zmiany podwyższonego ryzyka zostaną zostawione na kolejne w stosunku do niego wersje. JDK 18 to jednak edycja bardzo przejściowa. Nowy cykl releasowy przyniósł jak zwykle pewne dodatki “przyrostowe”, ale nie widzę dobrego powodu, żeby ktokolwiek musiał natychmiast rzucać się i upgradować do “osiemnastki” – widać, że twórcy dopiero się rozgrzewają i zbierają siły przed wdrożeniem nadchodzących, dużych inicjatyw jak Valhalla czy Loom, który w końcu niedawno ukazał się nareszcie w pierwszym oficjalnym preview.