Diversity w polskim IT
Adam Kukołowicz
Adam KukołowiczCo-founder @ Bulldogjob

Java 23 - wszystkie nowości

Java 23 została wydana, sprawdzamy wszystkie 12 JEP-ów, które trafiły do tej wersji.
25.09.20245 min
Java 23 - wszystkie nowości

Kolejna wersja Javy jest szeroko dostępna, więc nie pozostaje nam nic innego, jak omówić wszystkie nowości, które się w niej pojawiły.

Java 23, to wersja, która będzie obowiązywać przez kolejne pół roku - do marca 2025. W nowym cyklu wydawniczym wersje między LTS-ami (Long Term Support) służą raczej do spokojnego testowania nowych, większych funkcji, więc nie mamy tu do czynienia z dużą ilością stabilnych nowości. Niemniej znalazło się ich kilka wśród 12 JEP-ów dodanych w Javie 23.

Dla przypomnienia zmiany dzielą się na:

  • stable - dopracowane i włączone domyślnie dla wszystkich
  • preview - względnie stabilne, ale wymagające dopracowania; w kolejnych wersjach są możliwe zmiany, a dostęp do nich jest możliwy po skonfigurowaniu odpowiednich flag
  • incubator - funkcje eksperymentalne, które mogą się jeszcze znacznie zmienić lub mogą zostać całkowicie porzucone w przyszłym wydaniu; również wymagają włączenia flag

Nowy format dokumentacji

W Javie 23 dokumentacja JavaDoc może być pisana w Markdownie (JEP 467), co będzie zapewne łatwiejsze do czytania i pisania niż dotychczasowa mieszanka HTML i tagów @.

Wspierane są wszystkie najważniejsze funkcje Markdowna, w tym linki, tabele czy bloki kodu, a więc ten komentarz powinien się ładnie wyrenderować w dokumentacji:

/// Here is an example:
///
/// ```
/// /** Hello World! */
/// public class HelloWorld {
///     public static void main(String... args) {
///         System.out.println("Hello World!"); // the traditional example
///     }
/// }
/// ```

Można używać też tagów JavaDoc, takich jak {@inheritDoc}, @param, @return. Ta zmiana jest stabilna.

Kolejne zmiany w pattern matchingu

Chyba w każdej wersji Javy przez ostatnie 2 lata były jakieś zmiany w tym mechanizmie. Nie inaczej jest w Javie 23. Tym razem nowa funkcja preview (JEP 455) umożliwiająca sprawdzanie typów prymitywnych we wzorcach, instanceof i switch.

W skrócie chodzi o to, że teraz można dopasowywać wzorce po typie prymitywnym, co otwiera nowe możliwości i oszczędza nam zbędne rzutowanie. 

Przykładowo możesz teraz zrobić tak:

switch (x) {
    case int i -> System.out.println("It's an integer: " + i);
    case double d -> System.out.println("It's a double: " + d);
}

W przypadku instanceof chyba najlepiej pokazuje o co chodzi ten przykład z dokumentacji. Przed zmianami napisalibyśmy tak:

int i = 1000;
if (i instanceof byte) {    // false -- i cannot be converted exactly to byte
    byte b = (byte)i;       // potentially lossy
    ... b ...
}

Natomiast po możemy to zrobić lepiej:

if (i instanceof byte b) {
    ... b ...               // no loss of information
}

Mniej importów

Zmianą preview jest JEP 476 dotyczący importowania modułów. Twórcy Javy zauważyli, że na początku plików większość projektów ma zbyt wiele linijek zaczynających się od import. Nowa zmiana dodaje możliwość zaimportowania wszystkich pakietów wyeksportowanych przez moduł. Przykładowo, moduł java.base eksportuje m.in. java.io i java.lang. Więc teraz jeżeli zrobimy:

import java.base;

To tak jakbyśmy zaimportowali java.lang.*, java.io.* i kilkadziesiąt innych pakietów z java.base.

To już było

Teraz czas na całą litanię ulepszeń, które już były obecne w poprzednich wersjach Javy, czy to jako funkcje preview czy w inkubatorze.

JEP 466: drugie preview API do przetwarzania plików z klasami (Class-File API). To API umożliwia sprawne odczytywanie i zapisywanie plików zawierających klasy Javy. Ma zastąpić ASM, by łatwiej debugować, zmieniać i generować klasy w Javie.

JEP 469: Po raz 8 (!) w inkubatorze mamy API do obsługi wektorów. Co ciekawe w tym JEP-ie nie ma żadnych zmian, a po prostu dalsze prace zostały wstrzymane do czasu dołączenia zmian języka powiązanych z Projektem Valhalla do Javy. Valhalla to duży refactoring Javy jako takiej, więc zobaczymy ile jeszcze tu poczekamy.

JEP 473: To druga odsłona preview Stream Gatherers. Nie ma tu zmian od poprzedniej wersji, zespół Javy uważa, że nie zebrał jeszcze wystarczająco dużo feedbacku na temat nowej funkcji. Gatherer działa podobnie jak Collector, natomiast jest zaprojektowany by realizować kroki pośrednie w przetwarzaniu strumienia. Dodatkowo umożliwia przetwarzanie równoległe, co zawsze jest plusem.

JEP 477: Deklarowanie klas domniemanych i metod main - 3 raz jako preview. Tu w zasadzie chodzi o to, żeby HelloWorld był krótszy (oraz by było można pisać mniej boilerplate’u, gdy odpalamy pojedynczy plik Javy).

Teraz można zrobić:

void main() {
    System.out.println("Hello, World!");
}

Gdy nazwiemy plik HelloWorld.java i uruchomimy go poprzez komendę java HelloWorld.java to kompilator uzna, że ta klasa powinna się nazywać zgodnie z nazwą pliku i uruchomi funkcję main.

JEP 480: Structured Concurrency - brak zmian, czeka na więcej feedbacku od społeczności. Pozwala na realizowanie jednego dużego zadania, jako wiele mniejszych kroków, realizowanych w oddzielnych wątkach. Całość traktowana jest jak jedna jednostka pracy, stąd nazwa “ustrukturyzowana współbieżność”.

JEP 481: Scoped Values - trzeci raz jako preview, z drobnymi zmianami. Propozycja, która umożliwia współdzielenie między wątkami niemutowalnych danych, co ma być sprawniejsze i bardziej oszczędne niż używanie zmiennych “thread-local”, szczególnie w połączeniu z ustrukturyzowaną współbieżnością.

JEP 482: Drugi raz jako preview - bardziej elastyczna składnia konstruktorów. Wcześniej przed wywołaniem super(...) czy this(...) nie było zbyt wiele możliwości dodawania instrukcji. W nowej składni można dodawać takie instrukcje. Dzięki temu można np. sprawdzać wartości podane w konstruktorze i rzucić wyjątek, jeżeli nie mają one sensu. Więcej elastyczności zawsze jest mile widziane.

Drobne zmiany

Zmiany (stabilnej) doczekał się ZGC (JEP 474). Ten garbage collector domyślnie jest teraz pokoleniowy. Po prostu okazało się, że ten tryb działania daje lepsze rezultaty i stopniowo tryb niepokoleniowy zostanie wycofany.

Metody w sun.misc.Unsafe zostały oznaczone jako "do wyrzucenia w przyszłym wydaniu" (JEP 471).

I to tyle zmian w nowej Javie. Jak widać nie są one przełomowe. Do kolejnego wydania LTS mamy jeszcze rok i zapewne wtedy trafią do Javy wszystkie zmiany oznaczone teraz jako preview. Szkoda, że tak długo, bo jest ich sporo i są ciekawe.

<p>Loading...</p>