JavaRush /Blog Java /Random-PL /Java 14: co nowego?

Java 14: co nowego?

Opublikowano w grupie Random-PL
Problemy świata są problemami świata, a nowa Java jest realizowana zgodnie z harmonogramem. Oznacza to, że dokładnie raz na sześć miesięcy. Wersja Java 14 została wydana 17 marca i wprowadziła do języka kilka ciekawych innowacji skierowanych do programistów. Java 14: co nowego?  - 1Wśród nich znajduje się eksperymentalna obsługa słowa kluczowego record , obsługa dopasowywania wzorców w operatorze „ instancjaof ”, bardziej przyjazne dla użytkownika wyjątki NullPointerExceptions , rozszerzony „podgląd” bloków tekstu , zaktualizowany przełącznik domyślny i wiele więcej. Przypomnijmy, że wszystkie innowacje w Javie zaczynają się od propozycji rozszerzeń ( JEP, Java Enhancement Proposals ). Programiści proponują zmiany, są one przeglądane przez „oficjalnych” rodziców Java, a następnie część tych zmian jest akceptowana, po czym stają się częścią JDK. A teraz - o wszystkim w porządku.

JEP 359: Zapisy

Rekordy, zwane także Rekordami, są dostępne dla JDK 14 w trybie podglądu i jest to coś zupełnie nowego w Javie. Tak naprawdę mamy przed sobą nowy typ, który został opracowany podczas projektu Valhalla . Rekordy przypominają wyliczenia i pozwalają uprościć kod. Zasadniczo zastępują klasy, które mają stan, ale nie zachowują się. Mówiąc najprościej, istnieją pola, nie ma metod. W przypadku klas czasami musimy napisać dużo powtarzalnego kodu, który nie zawsze jest konieczny: konstruktory, akcesory, równości(), hashCode(), toString() itp. Aby uniknąć tego powtarzalnego kodu, Java planuje używać rekordu. Oto klasyczna wersja:
final class Triangle {
 	public final int x;
public final int y;
public final int z;

    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
Przejdźmy do Java 14 i użyjmy rekordu:
public record Triangle(int x, int y, int z){}
To wszystko. Należy pamiętać, że nagrania istnieją obecnie w formie podglądu, więc aby wypróbować je w praktyce należy pobrać jdk14 i wpisać komendę:
javac —enable-preview —release 14 Triangle.java
Rekordy to zajęcia, aczkolwiek z ograniczeniami. Nie mogą rozszerzać innych klas ani deklarować pól (z wyjątkiem private final, które odpowiadają komponentom deklaracji stanu). Zapisy są w sposób dorozumiany ostateczne i nie mogą być abstrakcyjne. Rekordy różnią się od zwykłych klas tym, że nie można oddzielić interfejsu API od jego reprezentacji. Ale utratę swobody rekompensuje zwiększona dokładność. Składniki rekordu są również domyślnie ostateczne.

JEP 305: Dopasowywanie wzorców na przykład (wersja zapoznawcza)

Funkcja Pattern Matching , wprowadzona w Javie 14 w wersji zapoznawczej, ma na celu połączenie sprawdzania typu obiektu i jego konwersji w operatorze instancjiof . Innymi słowy, przed Javą 14 istniałby na przykład następujący kod:
Object object = Violin;

if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
Jak widać musimy rzucić obiekt na klasę, której metod chcemy użyć. Teraz Java 14 i połączona funkcja Pattern Matching pozwalają zredukować kod do następującego:
Object object = Violin;

if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343: Narzędzie do pakowania (inkubator)

JDK 8 zawierał narzędzie javapackager zaprojektowane dla JavaFX. Jednak po oddzieleniu JavaFX od Javy wraz z wydaniem JDK 11 popularny pakiet javapackager nie był już dostępny. Javapackager był narzędziem do pakowania. Pozwoliło to na pakowanie aplikacji Java w taki sposób, że można je było zainstalować jak wszystkie inne „normalne” programy. Na przykład utwórz pliki exe dla użytkowników systemu Windows i uruchom aplikację Java jak człowiek - podwójnym kliknięciem. Oczywiście takiego narzędzia bardzo brakuje, więc JEP 343 wprowadził nowe narzędzie, jpackage , które pakuje aplikację Java w pakiet specyficzny dla platformy, zawierający wszystkie niezbędne zależności. Obsługiwane formaty pakietów dla konkretnej platformy:
  • Linux: deb i obr/min
  • macOS: pkg i dmg
  • Windows: MSI i EXE

JEP 345: Alokacja pamięci z obsługą NUMA dla G1

JEP 345 służy wyłącznie do implementacji obsługi NUMA (niejednolitego dostępu do pamięci). Są to heterogeniczne architektury dostępu do pamięci, czyli sposób na skonfigurowanie klastra mikroprocesorów w system wieloprocesorowy, w którym pamięć może być dystrybuowana lokalnie: każdy rdzeń procesora otrzymuje niewielką ilość pamięci lokalnej, podczas gdy inne rdzenie mają do niej dostęp. JEP 345 planuje wyposażyć moduł zbierający elementy bezużyteczne G1 w możliwość wykorzystania takich architektur. Takie podejście pomaga między innymi poprawić wydajność na bardzo wydajnych maszynach.

JEP 349: Transmisja strumieniowa wydarzeń JFR

Java Flight Recorder (JFR) jest teraz częścią OpenJDK i dlatego jest swobodnie dostępny. JDK 14 dodaje API do śledzenia na bieżąco zdarzeń JFR (JDK Flight Recorder), w szczególności do organizowania ciągłego monitorowania aktywnych i nieaktywnych aplikacji. Rejestrowane są te same zdarzenia, co w przypadku opcji bez przesyłania strumieniowego, z narzutem mniejszym niż 1%. W ten sposób wydarzenia będą transmitowane strumieniowo w tym samym czasie, co w przypadku opcji bez przesyłania strumieniowego. Jednakże JEP 349 nie może zezwalać na synchroniczne wywołania zwrotne dla odpowiedniego konsumenta. Nawet dane z zapisów przechowywanych w pamięci pośredniej nie powinny być dostępne. Technicznie rzecz biorąc, pakiet jdk.jfr.consumer w module jdk.jfr zostanie rozszerzony o funkcjonalność asynchronicznego dostępu do zdarzeń.

JEP 352: Nieulotne bufory mapowanych bajtów

Jak wiemy, interfejs API plików Java NIO (New IO) istnieje od wersji JDK 1.4, a następnie wprowadzono nowe ulepszenie o nazwie Path. Path to interfejs, który zastępuje klasę java.io.File jako reprezentację pliku lub katalogu, gdy pracujemy w Java NIO. JEP 352 rozszerza MappedByteBuffer, aby załadować część danych pliku do pamięci nieulotnej (NVM). Ta pamięć komputera, w której dane nie zostaną utracone nawet po wyłączeniu zasilania (często nazywana pamięcią tylko do odczytu), służy do trwałego przechowywania danych. Ta propozycja udoskonalenia języka Java udostępnia nowy moduł i klasę dla interfejsu API JDK: moduł jdk.nio.mapmode, który oferuje nowe tryby (READ_ONLY_SYNC, WRITE_ONLY_SYNC) do tworzenia mapowanych buforów bajtowych (MappedByteBuffer) odwołujących się do NVM.

JEP 358: Pomocne wyjątki NullPointer

Wyjątki NullPointerExceptions będą teraz bardziej przyjazne dla programistów. W tym sensie, że opis wyjątku będzie zawierał znacznie więcej informacji niż dotychczas. Dzieje się tak, ponieważ maszynę JVM nauczono dokładniej analizować instrukcje kodu bajtowego programu i może ona wskazywać, która zmienna prowadzi do wartości zerowej. Powiedzmy, że mamy kod:
a.getMessage().getUserInfo().getName()
W dowolnej najnowszej Javie otrzymamy zwykły dziennik błędów, który nie odpowiada na pytanie, kto dokładnie ma wartość null:
Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
A oto, co zapewni Ci Java 14, jeśli zdecydujesz się wypróbować tę funkcję podglądu:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
Ten łańcuch jest znacznie bardziej zrozumiały i pozwala znacznie szybciej uporać się z błędem.

JEP 361: Przełącz wyrażenia (standard)

Zaktualizowany operator Switch był dostępny w poprzednich wersjach Java 12 i 13, ale tylko jako funkcja podglądu, to znaczy nie był domyślnie włączony. Teraz w JDK 14 wszystko działa od razu po wyjęciu z pudełka. W Javie 14 wprowadzono nową, uproszczoną formę bloku przełączników z etykietami wielkości liter L -> .... Nowa forma w niektórych przypadkach upraszcza kod. Oto kilka przykładów. Załóżmy, że mamy wyliczenie opisujące dni tygodnia. Możemy napisać klasyczny kod (przed Java 14):
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
A oto opcja wykorzystująca Java 14:
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
Możesz także pisać bloki wielowierszowe i zwracać wartość za pomocą nowego słowa kluczowego Yield:
int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
Korzystając z nowego przełącznika, należy pamiętać o jeszcze kilku ważnych kwestiach . W szczególności należy pamiętać, że opcje muszą być wyczerpujące. Oznacza to, że dla wszystkich możliwych wartości musi istnieć odpowiednia etykieta przełącznika. Ponieważ wydajność jest teraz słowem kluczowym, w Javie 14 możliwa jest klasa o nazwie wydajność. Ogólnie rzecz biorąc, jeśli chcesz dowiedzieć się, jak korzystać z zaktualizowanych przełączników, przejdź do JEP 361 i przestudiuj. Jest tam wiele ciekawych informacji.

JEP 362: Wycofanie portów Solaris i SPARC

Jest mało prawdopodobne, aby wielu naszych czytelników pamiętało system operacyjny Solaris . Ten system operacyjny oparty na systemie UNIX, stworzony przez rodziców Javy, firmę Sun Microsystems, był używany głównie w serwerach opartych na architekturze SPARC... Za dużo nieznanych słów na centymetr kwadratowy? Nic wielkiego: JEP 362 kończy wsparcie dla platform Solaris/SPARC, Solaris/x64 i Linux/SPARC. Oznacza to, że ich porty są obecnie przestarzałe i w przyszłości najprawdopodobniej zostaną usunięte z OpenJDK. Jednakże starsze wersje Java (przed JDK 14) dotyczące portów Solaris/SPARC, Solaris/x64 i Linux/SPARC powinny działać bez modyfikacji. Jeżeli jesteś miłośnikiem historii i interesują Cię technologie z niedalekiej przeszłości, zajrzyj do Wikipedii i poczytaj o architekturze SPARС .

JEP 363: Usuń moduł zbierający śmieci Concurrent Mark Sweep (CMS).

Moduł zbierający śmieci CMS (Concurrent Mark Sweep) przeznaczony jest do usunięcia, ponieważ dwa lata temu został oznaczony jako przestarzały i pozostawiony bez konserwacji. Jednakże użytkownicy starszych wersji Java korzystających z CMS GC mogą odetchnąć - celem tego JEP nie jest usunięcie kreatora z wcześniejszych wydań JDK. Ponadto kombinacja algorytmów usuwania elementów bezużytecznych ParallelScavenge i SerialOld (działających z opcjami „-XX:+UseParallelGC -XX:-UseParallelOldGC”) stała się przestarzała.

JEP 364: ZGC na macOS i JEP 365: ZGC na Windows

Istnieje ciekawy moduł zbierający śmieci o nazwie Z Garbage Collector (ZGC) . Działa w trybie pasywnym i stara się minimalizować opóźnienia spowodowane zbieraniem śmieci: czas zatrzymania podczas korzystania z ZGC nie przekracza 10 ms. Może pracować z małymi i gigantycznymi kopcami (takimi, które zajmują wiele terabajtów). JEP 364 i JEP 365 to praktycznie bliźniaki. JEP 364 przenosi Z Garbage Collector do systemu MacOS. Część JEP opisuje również funkcjonalność kolektora służącą do zwalniania nieużywanej pamięci urządzenia, jak określono w JEP 351 , dzieje się to od Java 13. Implementacja ZGC w systemie macOS składa się z dwóch części:
  • Obsługa wielu mapowań pamięci w systemie macOS
  • Obsługa ZGC dla ciągłej rezerwacji pamięci
JEP 365 zapewnia obsługę ZGC już w systemie Windows, a także w trybie eksperymentalnym. Jest następująco:
  • Obsługa pamięci z wieloma mapowaniami
  • Obsługa mapowania pamięci na podstawie pliku strony do zarezerwowanej przestrzeni adresowej
  • Obsługa mapowania i usuwania mapowania dowolnych części sterty
  • Obsługa zatwierdzania i cofania dowolnych części sterty

JEP 366: Wycofaj kombinację ParallelScavenge + SerialOld GC

Ten JEP jest przestarzałą kombinacją algorytmów Parallel Scavenge i Serial Old. Tę kombinację należało włączyć ręcznie za pomocą parametrów wiersza poleceń -XX: + UseParallelGC -XX: -UseParallelOldGC. Autorzy uważają, że połączenie jest bardzo specyficzne, ale wymaga również znacznego wysiłku pielęgnacyjnego. Zatem teraz opcja -XX: UseParallelOldGC jest przestarzała i w przypadku jej użycia pojawi się ostrzeżenie.

JEP 367: Usuń narzędzia i interfejs API Pack200

Pack200 to format archiwum zoptymalizowany do przechowywania skompilowanych plików klas Java. To narzędzie zostało oznaczone jako przestarzałe od wersji Java 11. Teraz oficjalnie ogłoszono, że narzędzia API pack200, unpack200 i Pack200 zostaną usunięte z pakietu java.util.jar . Technologia ta została wprowadzona w Javie 5, aby poradzić sobie z bardzo ograniczoną przepustowością (modemy, aż strach to powiedzieć i pamiętam, 56 KB) i niewystarczającą ilością miejsca na dyskach twardych. Jakiś czas temu Java 9 wprowadziła nowe schematy kompresji. Zachęcamy programistów do korzystania z jlink .

JEP 368: Bloki tekstowe (drugi podgląd)

Bloki tekstowe pojawiły się po raz pierwszy w Javie 13. Są to wielowierszowe literały łańcuchowe, które eliminują potrzebę stosowania większości sekwencji ucieczki, automatycznie formatują ciąg znaków, a także umożliwiają programiście sformatowanie ciągu, jeśli to konieczne. Ta przydatna funkcja jest teraz dostępna w języku Java 14 (2. wersja zapoznawcza). Głównym celem bloków tekstowych jest usprawnienie obsługi mylących literałów wielowierszowych. To znacznie upraszcza odczytywanie i zapisywanie zapytań SQL, kodu HTML i XML oraz JSON. Przykład HTML bez bloków tekstowych:
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
Jak przedstawić to samo za pomocą bloków tekstowych:
String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
Separator otwierający to sekwencja trzech znaków cudzysłowu („” ”), po których następuje zero lub więcej spacji, a następnie ogranicznik wiersza. Treść rozpoczyna się od pierwszego znaku po ograniczniku wiersza ogranicznika otwierającego. Separator zamykający to sekwencja trzech znaków cudzysłowu _ ) została wybrana tak, aby znaki mogły być wyświetlane bez ucieczki, a także wizualnie odróżniały blok tekstu od literału ciągu. Na początku 2019 roku w JEP 355 zaproponowano bloki tekstu jako kontynuację JEP 326 (literały surowego ciągu znaków), ale zostały one wycofane. Później tego samego roku w JDK 13 wprowadzono funkcję podglądu bloków tekstu, a teraz w Java 14 dodano dwie nowe sekwencje ucieczki. Jest to terminator linii, oznaczony \, a drugi dla pojedynczej spacji, oznaczony /s. Przykład użycia znaków nowej linii bez bloków tekstu:
String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
A teraz z sekwencją ucieczki \<line-terminator>:
String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
Sekwencja ucieczki \s jest używana do uwzględnienia końcowych białych znaków, które domyślnie są ignorowane przez kompilator. Zachowuje wszystkie białe znaki, które go poprzedzają. Przykład:
String text1 = """
               line1
               line2 \s
               line3
               """;

String text2 = "line1\nline2 \nline3\n";
text1i text2są identyczne.

JEP 370: API dostępu do pamięci zagranicznej (inkubator)

Wiele popularnych bibliotek i programów Java ma dostęp do pamięci zewnętrznej. Na przykład Ignite, MapDB, Memcached i Netty ByteBuf API. W ten sposób mogą uniknąć kosztów i nieprzewidywalności związanej ze zbieraniem elementów bezużytecznych (szczególnie podczas obsługi dużych pamięci podręcznych), dzielić pamięć między wieloma procesami oraz serializować i deserializować zawartość pamięci poprzez mapowanie plików w pamięci (na przykład przy użyciu mmap). Jednak Java API nadal nie ma odpowiedniego rozwiązania umożliwiającego dostęp do pamięci zewnętrznej. JDK 14 zawiera wersję zapoznawczą interfejsu API dostępu do pamięci zagranicznej , który umożliwia aplikacjom Java bezpieczny i wydajny dostęp do obszarów pamięci poza stertą JVM przy użyciu nowych abstrakcji MemorySegment, MemoryAddress i MemoryLayout.

wnioski

Więc co o tym myślisz? W porównaniu do Java 13, nowa Java 14 oferuje o wiele więcej ważnych ulepszeń w różnych obszarach. Najprawdopodobniej najważniejsze dla programistów będą zaktualizowany przełącznik, rozszerzone wyjątki NullPointerExceptions i rekordy. Czy nie?.. Nie zapomnij wypróbować nowych funkcji Java 14, jest ona bardzo przydatna nawet dla początkujących. Powodzenia z Twoimi studiami!
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION