Co nowego w Javie 17?

Wersja długoterminowego wsparcia (LTS) języka Java i platformy środowiska wykonawczego Java 17 została uruchomiona 14 września 2021 r. Dowiedzmy się, co nowego w Javie 17 i czy należy uaktualnić.

Wiele aplikacji używa starszych wersji Javy, w tym wcześniejszych wersji LTS Javy: Java 11 i Java 8.

Dlaczego firmy powinny dokonać aktualizacji do najnowszej wersji Java? Aktualizacja do Jawa 17 wymaga wysiłku, głównie w celu maksymalnego wykorzystania nowych funkcji i funkcji wewnątrz JVM.

Wiele firm używa obrazów Docker i Docker do łatwego przejścia na Javę 17 przy minimalnym nakładzie pracy i czasu. Deweloperzy mogą definiować swoje potoki ciągłej integracji/wdrażania (CI/CD) i uruchamiać wszystko w obrazach platformy Docker. Nie wpłynie to na inne zespoły korzystające ze starszych wersji Javy, ponieważ mogą one korzystać ze starych obrazów platformy Docker.

Funkcje JAVA 17

Obsługa macOS i AArch64

Jedną z krytycznych funkcji JVM dodanych do tej wersji jest rozszerzenie obsługi systemu macOS w architekturze AArch64 przy użyciu JEP 391. Będzie ona obsługiwać najnowszą serię procesorów (M1) Apple wydanych wraz z ich komputerami w zeszłym roku.

Niekoniecznie jest to wielka sprawa dla użytkowników tych platform, ponieważ niektórzy dostawcy uruchomili wersje JDK, które obsługują tę architekturę, a nawet zwracają wsparcie z Javy 8. Jednak oficjalna pieczęć zatwierdzenia jest niezbędna, aby zapewnić przyszłą konserwację i wsparcie dla Platforma. Dla porównania, wsparcie dla platformy Linux/AArch64 zostało dodane do Javy 9 i Windows/AArch64 w Javie 16.

Zapieczętowane klasy

Zapieczętowane klasy to funkcja wprowadzona w Javie 17. Funkcja zapieczętowanych klas zakończyła fazę próbną i stała się oficjalną platformą i językiem w Javie 17. Pozwala programiście określić dopuszczalne podtypy, które może mieć typ i uniemożliwić innym rozszerzanie lub wdrażanie go w sposób, który nie jest zamierzony.

Klasy zapieczętowane umożliwiają również kompilatorowi generowanie błędów w czasie kompilacji podczas próby przekonwertowania niezapieczętowanego typu na niedozwolony podtyp. Java 17 wprowadza również nowy potok renderowania dla aplikacji AWT/Swing, które działają w systemie macOS przy użyciu interfejsu Apple Metal API zamiast OpenGL. Ma ulepszony interfejs API i ulepszone funkcje generowania liczb losowych.

Zmiany, usunięcia i ograniczenia w Javie 17

Java 17 wprowadza również kilka zmian, usunięć i nowych ograniczeń.

Hermetyzacja wewnętrznych elementów JDK

Jedną ze zmian jest zakończenie procesu enkapsulacji JDK Internals. Po raz pierwszy zostało to wprowadzone w Javie 9 i wyświetlało ostrzeżenia w czasie wykonywania, gdy użytkownik próbował użyć odbicia lub podobnego, aby obejść zwykłe ograniczenia dotyczące korzystania z wewnętrznych interfejsów API. Dodano również argumenty wiersza poleceń, aby regulować to zachowanie.

Od Javy 9 stworzono różne interfejsy API, aby oferować jednolity sposób wykonywania najczęściej używanych zadań; użytkownicy będą korzystać z tych interfejsów API wewnętrznie. W Javie 16 wartość domyślna została zmieniona z ostrzeżenia na wyłączenie dostępu do zgłaszania wyjątku. Jednak używa argumentu wiersza polecenia do zmiany zachowania.

W Javie 17 argument wiersza poleceń został wyeliminowany i możliwe jest dezaktywowanie tego ograniczenia. Oznacza to, że cały nieautoryzowany dostęp do tych wewnętrznych interfejsów API jest teraz chroniony.

Zawsze ścisła semantyka zmiennoprzecinkowa

Dodatkowe „usunięcie” można opisać jako ponowne wprowadzenie semantyki Always-Strict Floating Point. Java 1.2 wprowadziła modyfikacje domyślnej semantyki zmiennoprzecinkowej w Javie, która pozwala maszynie JVM na wymianę niewielkiej ilości precyzji w obliczeniach zmiennoprzecinkowych w celu poprawy wydajności. W klasach i metodach, w których trzeba było stosować ścisłą semantykę, dodano słowo kluczowe strictfp. Od tego czasu do procesorów wprowadzono różne typy zestawów instrukcji, dzięki czemu ścisła semantyka zmiennoprzecinkowa może być używana bez zbędnych kosztów. Wyeliminowano potrzebę implementacji domyślnej lub ścisłej semantyki.

Java 17 usuwa poprzednią domyślną semantykę, a wszystkie operacje zmiennoprzecinkowe są wykonywane ściśle. Termin strictfpis jest nadal obecny. Jednak nie ma to żadnego wpływu i powoduje ostrzeżenie w czasie kompilacji.

Kompilacja z wyprzedzeniem (AOT)

Java 9 wprowadziła kompilację z wyprzedzeniem (AOT) jako funkcję eksperymentalną, która wykorzystuje kompilator Graal, a kod JIT został napisany przy użyciu Javy. Java 10 uczyniła kompilator Graal użytecznym jako kompilator JIT w OpenJDK poprzez włączenie interfejsu JVMCI. Odkąd został wydany, jest to ogromna poprawa. Kompilator Graala osiągnął ogromne postępy i ma swoją JVM pod nazwą GraalVM.

Aktywacja RMI

Aktywacja RMI została wyeliminowana w JEP 407 po jego usunięciu z Javy 8 i ostatecznie przestarzałe i oznaczone jako wymagane do usunięcia w Javie 15. Aktywacja RMI zapewniła metodę włączania rozproszonych obiektów na żądanie przy użyciu RMI. Jednak zużycie było minimalne, a w teraźniejszości dostępna jest lepsza alternatywa. Na pozostałą część RMI nie ma wpływu eliminacja części aktywacji.

Usuwanie interfejsu API apletu

Applet API został ostatecznie przeznaczony do usunięcia przez JEP 398, początkowo usunięty w Javie 9. Applet API umożliwił zintegrowanie kontrolek Java AWT/Swing ze stroną internetową w przeglądarce. Jednak żadna nowoczesna przeglądarka nie obsługuje tego, co oznacza, że ​​aplety były zasadniczo niedostępne w ciągu ostatniej dekady.

Menadżer ochrony

Najważniejszą deprecjacją jest to, że jest to kierownik ds. bezpieczeństwa ( JEP 411). Security Manager jest używany przez jakiś czas od wersji Java 1.0. Został zaprojektowany w celu ograniczenia tego, co Java może robić lokalnie na komputerze, na przykład ograniczania dostępu do sieci, plików i innych zasobów sieciowych. Próbuje również piaskownicy kodu, który nie jest zaufany, blokując odbicie i określone interfejsy API.

Koniec programu Security Manager rozpoczął się w Javie 12. Dodano argument wiersza polecenia, aby zablokować korzystanie z menedżera zabezpieczeń w czasie wykonywania. Zmiana dokonana w języku Java 17 oznacza, że ​​podczas próby ustawienia menedżera zabezpieczeń w maszynie JVM zostanie wygenerowane ostrzeżenie w czasie wykonywania, albo z wiersza poleceń, albo dynamicznie w czasie wykonywania.

Funkcje inkubatora i podglądu

Wielu zastanawiało się, czy Java 17 będzie miała jakiekolwiek funkcje podglądu i inkubatora, biorąc pod uwagę, że Java 17 była promowana jako wersja wspierana przez długi czas. Java 17 ma dwa moduły inkubatorów i funkcję podglądu!

Wektorowy interfejs API

Wektorowy interfejs API ( JEP 414) znajduje się obecnie w drugiej fazie inkubatora. Interfejs API umożliwia programistom zdefiniowanie obliczeń wektorowych, które kompilator JIT następnie przekonwertuje na odpowiednią instrukcję wektorową obsługiwaną przez architekturę procesora, na której działa JVM (na przykład przy użyciu zestawów instrukcji SSE lub AVX).

Wcześniej programiści musieli używać funkcji skalarnych lub budować biblioteki natywne, które były specyficzne dla platformy. Implementacja Vector API w Javie zapewnia również płynny mechanizm awaryjny, który był skomplikowany we wcześniejszych wersjach.

Standaryzacja Vector API umożliwia klasom w JDK korzystanie z niego. Metody mismatch() Java Arrays można zmienić tak, aby działały w języku Java, eliminując konieczność utrzymywania i pisania implementacji dla wielu platform w JVM.

Interfejs API funkcji obcych i pamięci

Dodatkowa funkcja inkubatora nosi nazwę Foreign Function & Memory API ( JEP 412). Jest to ewolucja i połączenie dwóch innych modułów inkubatorów Javy 16 czyli The Foreign Linker API ( JEP 389) i API pamięci obcej ( JEP 393). Oba zapewniają dostęp do natywnej pamięci i kodu przy użyciu statycznie typowanego programowania napisanego w Javie.

Dopasowanie wzorca dla przełącznika

Ostatnią cechą podglądu języka zawartego w Javie 17 jest włączenie funkcji Pattern Matching for Switch ( JEP 406). Ta funkcja językowa rozszerza wyrażenia i instrukcje przełącznika zgodnie z typem, podobnie do składni używanej przez Dopasowywanie wzorców (JEP 394), który stał się standardem w Javie 16.

W przeszłości, jeśli chciałeś wykonywać różne działania w oparciu o dynamiczną naturę obiektu, musiałeś zbudować łańcuch if-else przy użyciu instancji sprawdzeń, takich jak:

String type(Object o) {
  if (o instanceof List) {
    return "A List of things.";
  }
  else if (o instanceof Map) {
    return "A Map! It has keys and values.";
  }
  else if (o instanceof String) {
    return "This is a string.";
  }
  else {
    return "This is something else.";
  }
}

Łącząc wyrażenie przełącznika oraz nową funkcję dopasowywania wzorców dla przełączników, proces można zredukować do czegoś podobnego do:

String type(Object o) {
  return switch (o) {
    case List l -> "A List of things.";
    case Map m -> "A Map! It has keys and values.";
    case String s -> "This is a string.";
    default -> "This is something else.";
  };
}

Jak mogłeś zauważyć, jest deklaracja zmiennej w trakcie sprawdzania. Podobnie jak inne zmienne w Pattern, dopasowanie instancji wskazuje, że ten obiekt został sprawdzony i rzutowany i jest dostępny ze zmiennej w jej bieżącym obszarze.

Funkcja podglądu to kolejny krok w kierunku dopasowania wzorców. Następnym krokiem jest uwzględnienie możliwości dekonstrukcji tablic i rekordów.

Czy powinieneś uaktualnić do Javy 17?

Tak, musisz stale aktualizować do najnowszej wersji, ale nie tak szybko, jak pierwszego dnia. Oprogramowanie i biblioteki, z których korzystasz, mogły nie zostać zaktualizowane w celu zapewnienia zgodności z Javą 17, więc być może trzeba będzie trochę poczekać, aż będzie gotowe.

Jeśli utkniesz z wersją Java LTS, taką jak Java 8 lub Java 11, istnieje wiele opcji w języku i samej JVM, które wymagają uaktualnienia do wersji Java 17. Ponieważ jest to długoterminowa wersja konserwacyjna, istnieje duża szansa, że ​​Twoje środowisko produkcyjne zostanie ostatecznie zaktualizowane do wersji Java 17.

Jeśli zaczynasz zupełnie nowy projekt lub jesteś w trakcie przygotowywania projektu do obsługi Javy 17, przejście na Javę 17 wcześniej niż później jest prawdopodobnie najbardziej efektywnym wyborem, ponieważ zmniejsza koszty przeniesienia. Pozwala to również programistom pracującym nad projektem wykorzystać wszystkie najnowsze funkcje i stronę ops.

Możesz skorzystać z wielu ulepszeń, które pojawiły się w ciągu ostatnich kilku lat, takich jak ulepszona obsługa kontenerów działających w Javie, a także nowe implementacje modułu odśmiecania pamięci o niskim opóźnieniu.