Po sześciu miesiącach prac rozwojowych firma Oracle wydała platformę Java SE 16 (Java Platform, Standard Edition 16), której etalonową implementacją jest otwarty projekt OpenJDK. W Java SE 16 zachowano wsteczną kompatybilność z poprzednimi wersjami platformy Java, wszystkie wcześniej napisane projekty Java będą działać bez zmian pod nową wersją. Gotowe do zainstalowania pakiety Java SE 16 (JDK, JRE i Server JRE) są przygotowane dla systemów Linux (x86_64, AArch64), Windows i macOS. Opracowana w ramach projektu OpenJDK etalonowa implementacja Java 16 jest całkowicie otwarta na licencji GPLv2 z wyjątkami GNU ClassPath, które zezwalają na dynamiczne wiązanie z komercyjnymi produktami.
Java SE 16 została zakwalifikowana jako wydanie z normalnym okresem wsparcia, aktualizacje będą wydawane do następnego wydania. Jako wersję z długoterminowym wsparciem (LTS) należy używać Java SE 11, której aktualizacje będą wydawane do 2026 roku. Następne wydanie LTS planowane jest na wrzesień 2021 roku. Przypominamy, że od wydania Java 10 projekt przeszedł na nowy proces rozwoju, zakładający krótszy cykl wytwarzania nowych wydań. Nowa funkcjonalność rozwija się teraz w jednej stale aktualizowanej gałęzi master, do której włączane są gotowe zmiany, a co sześć miesięcy gałęzie te są odgałęziane do stabilizacji nowych wydań.
Podczas przygotowywania nowego wydania prace rozwoju zostały przeniesione z systemu kontroli wersji Mercurial na Git oraz platformę współpracy GitHub. Oczekuje się, że migracja poprawi wydajność operacji z repozytorium, zwiększy efektywność przechowywania, zapewni dostęp do zmian w całej historii projektu, poprawi wsparcie dla przeglądania kodu oraz umożliwi korzystanie z API do automatyzacji procesów roboczych. Dodatkowo, stosowanie Gita i GitHuba czyni projekt bardziej atrakcyjnym dla nowicjuszy i programistów przyzwyczajonych do Gita.
Do nowości w Java 16 można zaliczyć:
- Dodano eksperymentalne moduł jdk.incubator.vector z implementacją API Vector, oferującym funkcje dla obliczeń wektorowych, które są realizowane z wykorzystaniem instrukcji wektorowych procesorów x86_64 i AArch64, umożliwiając jednoczesne zastosowanie operacji do wielu wartości (SIMD). W przeciwieństwie do możliwości automatycznej wektoryzacji operacji skalarnych w kompilatorze JIT HotSpot, nowa API pozwala na pełną kontrolę nad wektoryzacją w celu równoległego przetwarzania danych.
- W kodzie JDK i VM HotSpot, napisanym w C++, dozwolone jest korzystanie z możliwości, które pojawiły się w specyfikacji C++14. Wcześniej dozwolone było używanie standardów C++98/03.
- W zbieraczu śmieci ZGC (Z Garbage Collector), działającym w trybie pasywnym i minimalizującym opóźnienia związane z zbieraniem śmieci, dodano możliwość równoległego przetwarzania stosów wątków bez wstrzymywania działania wątków aplikacji. W ZGC pozostały jedynie operacje wymagające zatrzymania, które mają stałe opóźnienia, zazwyczaj nie przekraczające kilku setek mikrosekund.
- W klasach SocketChannel, ServerSocketChannel i java.nio.channels dodano wsparcie dla gniazd Unix (AF_UNIX).
- Zrealizowano port dla dystrybucji Linux Alpine z domyślną biblioteką C musl, popularną w środowiskach kontenerowych, mikroserwisowych, chmurowych oraz w systemach wbudowanych. Proponowany port w takich środowiskach pozwala na uruchamianie programów Java jako zwykłych aplikacji. Dodatkowo, za pomocą jlink można usunąć wszystkie nieużywane moduły i utworzyć minimalne środowisko potrzebne do uruchomienia aplikacji, co umożliwia tworzenie specyficznych dla danych aplikacji kompaktowych obrazów.
- Zrealizowano mechanizm Elastic Metaspace, optymalizujący operacje przydzielania i zwracania pamięci zajmowanej przez metadane klas (metaspace) w JVM HotSpot. Zastosowanie Elastic Metaspace zmniejsza fragmentację pamięci, obniża koszty w ładowarce klas oraz korzystnie wpływa na wydajność długoterminowych aplikacji serwerowych dzięki szybszemu zwrotowi pamięci zajmowanej przez nieużywane metadane klas do systemu operacyjnego. Dla wyboru trybu zwalniania pamięci po usunięciu klas zaproponowano opcję „-XX:MetaspaceReclaimPolicy=(balanced|aggressive|none)”.
- Dodano port JDK dla systemów Windows działających na sprzęcie z procesorami opartymi na architekturze AArch64.
- Zaproponowano trzeci wstępny wariant API Foreign-Memory Access, który umożliwia aplikacjom Java bezpieczny i wydajny dostęp do obszarów pamięci poza stertą Java, manipulując nowymi abstrakcjami MemorySegment, MemoryAddress i MemoryLayout.
- Wdrażono eksperymentalne API Foreign Linker, które zapewnia dostęp z Java do kodu natywnego. Wraz z API Foreign-Memory nowy interfejs programistyczny znacznie upraszcza tworzenie powłok nad tradycyjnymi bibliotekami współdzielonymi.
- Dodano narzędzie jpackage, które pozwala tworzyć pakiety dla samodzielnych aplikacji Java. Narzędzie opiera się na javapackagerze z JavaFX i umożliwia tworzenie pakietów w formatach, które są natywne dla różnych platform (msi i exe dla Windows, pkg i dmg dla macOS, deb i rpm dla Linux). Pakiety zawierają wszystkie niezbędne zależności.
- Włączono z domyślną wartością ścisłą enkapsulację wszystkich wewnętrznych elementów JDK, z wyjątkiem krytycznych API, takich jak sun.misc.Unsafe. Wartość opcji „—illegal-access” jest teraz domyślnie ustawiona na „deny” zamiast „permit”, co oznacza zablokowanie prób dostępu z kodu do większości wewnętrznych klas, metod i pól. Aby obejść to ograniczenie, należy użyć opcji „—illegal-access=permit”.
- Zdobiono stabilizację realizacji dopasowania wzoru w operatorze „instanceof”, który pozwala od razu określić zmienną lokalną do odniesienia do sprawdzonej wartości. Na przykład można od razu pisać „if (obj instanceof String s && s.length() > 5) {.. s.contains(..) ..}” bez wyraźnego określenia „String s = (String) obj”. Było: if (obj instanceof Group) { Group group = (Group) obj; var entries = group.getEntries(); } Teraz można obejść się bez określenia „Group group = (Group) obj”: if (obj instanceof Group group) { var entries = group.getEntries(); }
- Zdobiono stabilizację realizacji słowa kluczowego „record”, które zapewnia kompaktową formę definiowania klas, pozwalając na pominięcie wyraźnego określania różnych niskopoziomowych metod, takich jak equals(), hashCode() i toString(), w przypadkach, gdy dane są przechowywane tylko w polach, a ich działanie nie zmienia się. Gdy w klasie używane są standardowe implementacje metod equals(), hashCode() i toString(), można obejść się bez ich jawnego określenia: public record BankTransaction(LocalDate date, double amount, String description) {}
Ta deklaracja spowoduje automatyczne dodanie implementacji metod equals(), hashCode() i toString() w dodatku do konstruktora oraz metod zarządzających zmianą danych (getter).
- Zaproponowano drugi wstępny wariant klas i interfejsów zapieczętowanych („sealed”), które nie mogą być wykorzystywane przez inne klasy i interfejsy do dziedziczenia, rozbudowy lub nadpisywania implementacji. Klasy zapieczętowane zapewniają również bardziej deklaratywny sposób ograniczenia wykorzystania superclassa niż modyfikatory dostępu, oparty na wyraźnym wymienieniu podklas dozwolonych do rozszerzenia. package com.example.geometry; public sealed class Shape permits com.example.polar.Circle, com.example.quad.Rectangle, com.example.quad.simple.Square {…}
Źródło: opennet.ru
