JavaRush /Blog Java /Random-PL /Java 13: Nowe funkcje

Java 13: Nowe funkcje

Opublikowano w grupie Random-PL
Przyzwyczailiśmy się już do tego, że nowe wydanie JDK pojawia się co pół roku. Póki co takie podejście się sprawdza, a obawy części deweloperów, że nie nadążą z aktualizacjami, okazały się daremne: zmian sześciomiesięcznych jest niewiele i nie są one tak globalne jak wcześniej. Cóż, początkujący programiści mogą w ogóle nie zauważyć innowacji. Java 13: nowe funkcje - 1Jednak dla przyszłych twórców oprogramowania lepiej jest być na bieżąco z innowacjami. W tym artykule będziemy tradycyjnie opisywać zaakceptowane propozycje przedłużenia (JEP). Java 13 zawiera tylko pięć JEP i 76 nowych elementów biblioteki podstawowej (z czego prawie połowa to proste dodatki do pakietu java.io).

JEP 355 : Bloki tekstowe (podgląd)

Zacznijmy od zmiany składni języka. Najważniejszymi z nich są bloki tekstowe. Pozwalają uniknąć uciekających znaków i wiedzą, jak formatować ciągi znaków. Być może pamiętasz , że JDK 12 nie zawierał oczekiwanej funkcji Raw String Literals (JEP 326) do pracy z literałami łańcuchowymi. W Javie 13 został zastąpiony przez JEP 355 z blokami tekstowymi. Prawdopodobnie pamiętasz, że w Javie ciąg znaków jest zawijany w podwójne cudzysłowy. To dobrze, ale problem polega na tym, że linia nie może zajmować więcej niż jednej linii pliku źródłowego (aby uniknąć pomylenia z linią Java, będziemy tutaj nazywać linię pliku „linią”). Cóż, przejdźmy dalej i użyjmy na przykład symbolu, \njeśli wymagane jest przerwanie lub połączenie wyrażeń wielowierszowych. Nie wygląda to zbyt ładnie! Literały tekstowe z osadzonymi fragmentami HTML, XML, SQL lub JSON są szczególnie kłopotliwe. Całe to uciekanie, łączenie i ręczna edycja sprawiają, że kod jest niewygodny do napisania i trudny do odczytania. Bloki tekstowe próbują rozwiązać ten problem. Zaczynają się... potrójnymi cudzysłowami i kończą na nich (wiem, nie brzmi to zbyt dobrze). Wszystko pomiędzy cudzysłowami jest interpretowane jako część linii, włączając znaki nowej linii. Bloków tekstowych można używać dokładnie tak samo, jak standardowych literałów tekstowych, a Java kompiluje kod w ten sam sposób. Po cudzysłowie otwierającym musi nastąpić ogranicznik wiersza; bloków tekstowych nie można używać w jednym wierszu, więc kod
String smallBlock = """Only one line""";
spowoduje następujące błędy:
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
   String smallBlock = """Text Block""";
                          ^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
   String smallBlock = """Text Block""";
                                   	^
Prosty fragment HTML można teraz zapisać w następujący sposób:
String htmlBlock = """
               	<html>
                 	<body>
                   	<p>CodeGym Web page</p>
                 	</body>
               	<html>
         	     """;
Wspomnijmy o kilku subtelnościach, o których lepiej pamiętać podczas korzystania z bloków tekstu. Umieszczenie cudzysłowów zamykających okazuje się ważne: określa sposób obsługi sporadycznych białych znaków. W powyższym przykładzie cudzysłowy zamykające są wyrównane z wcięciem tekstu HTML. W tym przypadku kompilator usunie spacje wcięć i w rezultacie otrzymamy linię taką jak ta:
<html>
  <body>
    <p>My web page</p>
  </body>
</html>
Notatka:taka linia będzie zawierać znak nowej linii na końcu linii. Jeśli nie jest to konieczne, cudzysłów zamykający „” można umieścić bezpośrednio po znaczniku </html>. Jeśli przesuniemy cudzysłów zamykający bliżej lewego marginesu, zmieni to wielkość usuwanego wcięcia. Gdybyśmy przesunęli je o dwie spacje w lewo, dodalibyśmy po dwie spacje na wcięcie do każdej linii. Przesunięcie do lewej krawędzi spowoduje zachowanie całego dopełnienia. Przesunięcie cudzysłowu dalej w prawo nie będzie miało żadnego efektu i nie spowoduje dodania kolejnych wcięć. Bloki tekstowe zostały uwzględnione w JDK 13 jako funkcja podglądu. Oznacza to, że nie są one jeszcze uwzględnione w odpowiedniej specyfikacji języka Java. Oznacza to, że nie jest jasne, czy ta funkcja stanie się trwałą częścią języka, czy też będzie tu tylko gościem. Obecnie programiści mogą przetestować tę funkcję i wyrazić swoją opinię na jej temat. Od tego będzie zależeć los bloków tekstowych: tę funkcję można ulepszyć, a jeśli Ci się nie spodoba, można ją całkowicie usunąć. Jeśli chcesz wypróbować bloki tekstu w praktyce, pamiętaj, że funkcje podglądu muszą być wyraźnie uwzględnione, aby można było je skompilować i uruchomić. Kompilacja:

javac --enable-preview --release 13 TextBlock.java
Aby uruchomić aplikację, musisz włączyć funkcje podglądu:

java --enable-preview TextBlock
Klasa Stringma trzy nowe metody, które uzupełniają tę zmianę języka:
  • formatted(): Sformatuj ciąg znaków, używając samego ciągu jako ciągu formatującego. Równoważne wyzwaniuformat(this, args)
  • stripIndent(): Usuwa losowe spacje z ciągu. Jest to przydatne, jeśli czytasz ciągi wielowierszowe i chcesz zastosować to samo wykluczenie białych znaków, co w przypadku jawnej deklaracji.
  • translateEscapes(): Zwraca ciąg znaków z sekwencjami specjalnymi (takimi jak \ r), przetłumaczonymi na odpowiednią wartość Unicode.
Co ciekawe, metody te dopiero się pojawiły, ale są już oznaczone jako przestarzałe ... Taki stan rzeczy sugeruje, że mogą zostać usunięte w przyszłej wersji JDK. Dodanie nowej metody i natychmiastowe porzucenie jej wydaje się nieco ekscentryczne. Należy jednak pamiętać, że metody te są powiązane z funkcją podglądu, którą można zmienić lub usunąć. Być może wprowadzenie adnotacji @PreviewFeaturepomogłoby w takich sytuacjach, jednak nie jest ona jeszcze uwzględniona w JDK (choć z dużym prawdopodobieństwem pojawi się w JDK 14).

JEP 354 : Wyrażenie przełączające (podgląd)

W Javie 12 wprowadzono propozycję nowej formy zapisu wyrażeń za pomocą instrukcji switch - JEP 325 . Okazało się, że jest to pierwsza funkcja podglądowa, a jej losy udowadniają, że zgłaszanie propozycji użytkownikom to świetny pomysł. Przed wersją JDK 12 switchmożna było go używać tylko jako instrukcji wykonującej akcję, ale nie zwracającej wyniku. Ale w Javie 12 umożliwiono użycie go switchjako wyrażenia zwracającego wynik, który można przypisać do zmiennej. Wprowadzono inne zmiany w składni instrukcji case w switch. Spójrzmy na przykład z JEP, aby zrozumieć, jak to działa.
int numberOfLetters;
switch(dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
    numberOfLetter = 6;
    break;
  case TUESDAY
    numberOfLetter = 7;
    break;
  case THURSDAY
  case SATURDAY
    numberOfLetter = 8;
    break;
  case WEDNESDAY
    numberOfLetter = 9;
    break;
  default:
   throw new IllegalStateException("Huh?: " + day);
}
W tym przykładzie używamy wartości, dayOfWeekaby przypisać wartość do numberOfLetters. Ze względu na specyfikę pracy operatora switch, kod ten nie należy do najpiękniejszych i łatwo o pomyłkę. Po pierwsze, jeśli zapomnimy zastosować instrukcję breakdo każdej grupy etykiet przypadków, domyślnie przejdziemy do następnej grupy etykiet spraw. Może to prowadzić do błędów, które są trudne do znalezienia. Po drugie, musimy zdefiniować każdą grupę etykiet przypadków. Jeśli zapomnimy, oczywiście otrzymamy błąd kompilatora, jednak ta opcja nie jest idealna. Nasz kod jest również dość szczegółowy, ponieważ każda wartość dayOfWeekmusi mieć własną etykietę wielkości liter. Stosując nową składnię, otrzymujemy znacznie czystszy i mniej podatny na błędy kod:
int numberOfLetters = switch (dayOfWeek) {
   case MONDAY, FRIDAY, SUNDAY -> 6;
   case TUESDAY -> 7;
   case THURSDAY, SATURDAY -> 8;
   case WEDNESDAY -> 9;
   default -> throw new IllegalStateException("Huh?: " + day);
};
Teraz musimy dokonać przypisania tylko raz (na podstawie switchwartości zwracanej przez wyrażenie) i możemy użyć listy rozdzielanej przecinkami dla etykiet przypadków. A ponieważ nie używamy operatora break, eliminujemy problemy z nim związane. Składnia wyrażeń switchpozwala nam używać składni starszego stylu, więc w JDK 12 możemy zapisać to w ten sposób:
int numberOfLetters = switch (dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
   break 6;
  case TUESDAY
   break 7;
  case THURSDAY
  case SATURDAY
   break 8;
  case WEDNESDAY
   break 9;
  default:
   throw new IllegalStateException("Huh?: " + day);
};
Według społeczności Java używanie przeciążenia breakdo określenia wartości zwracanej może być mylące. Język Java pozwala także na użycie break(i continue) z etykietą, taką jak operator bezwarunkowego skoku goto. JEP 354 zmienił to użycie break, więc w Javie 13 nasz kod nieznacznie się zmienia:
int numberOfLetters = switch (dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
   yield 6;
  case TUESDAY
   yield 7;
  case THURSDAY
  case SATURDAY
   yield 8;
  case WEDNESDAY
   yield 9;
  default:
   throw new IllegalStateException("Huh?: " + day);
};
Następne trzy JEP są powiązane z wirtualną maszyną Java.

Archiwum dynamicznego CDS JEP 350

To rozszerzenie umożliwia dynamiczną archiwizację klas po zakończeniu wykonywania aplikacji Java. CDS lub Class Data Sharing pozwala na spakowanie wszystkich klas uruchamianych przy uruchomieniu do specjalnego archiwum class data sharing, domyślnie korzystając z listy tych samych klas. Prowadzi to do znacznego przyspieszenia uruchamiania aplikacji i oszczędzania pamięci RAM. Wcześniej korzystanie z AppCDS było wieloetapowym procesem, który obejmował utworzenie listy odpowiednich klas i wykorzystanie tej listy do utworzenia archiwum, które będzie używane w kolejnych uruchomieniach. Teraz wystarczy jedno uruchomienie aplikacji z flagą -XX: ArchiveClassesAtExitwskazującą lokalizację, w której zostanie zapisane archiwum. Dzięki takiemu podejściu klasy są automatycznie pakowane do archiwum po normalnym zatrzymaniu aplikacji.

JEP 351 ZGC : Cofnij zatwierdzenie nieużywanej pamięci

Rok temu JDK 11 wprowadził ZGC, eksperymentalny, skalowalny moduł zbierający elementy bezużyteczne o niskim opóźnieniu. Początkowo ZGC zachowywał się dość dziwnie: nie pozwalał na zwrot pamięci do systemu operacyjnego, nawet jeśli nie była już potrzebna. W niektórych środowiskach, takich jak kontenery, gdzie zasoby są wykorzystywane przez wiele usług jednocześnie, może to ograniczyć skalowalność i wydajność systemu. Kopiec ZGC składa się z tak zwanych ZPages. Kiedy ZPages zostaną usunięte podczas cyklu zbierania śmieci, zostaną one zwrócone do ZPageCache. Strony Z w tej pamięci podręcznej są uporządkowane według tego, jak ostatnio były używane. W Javie 13 ZGC zwróci do systemu operacyjnego strony, które zostały zidentyfikowane jako nieużywane przez dłuższy czas. Dzięki temu można je ponownie wykorzystać do innych procesów.

JEP 353 Ponowna implementacja starszego interfejsu API gniazda

Obie implementacje API java.net.Socketto java.net.ServerSocketnadal JDK 1.0. W tym i wszystkich kolejnych pakietach JDK implementacja tych interfejsów API wykorzystuje kilka technik (takich jak użycie stosu wątków jako bufora we/wy), które czynią je nieelastycznymi i trudnymi w utrzymaniu. Aby rozwiązać ten problem, w JDK 13 udostępniono nową implementację NioSocketImpl. Nie wymaga już kodu natywnego, co ułatwia przenoszenie na różne platformy. Klasa ta korzysta również z istniejącego mechanizmu buforowania pamięci podręcznej (unikając używania w tym celu stosu wątków) i java.util.concurrentmetod blokowania, a nie synchronizowanych. Uprości to integrację ze światłowodami firmy Project Loom .

Nowe interfejsy API

Wspomnieliśmy wcześniej, że Java 13 zawiera 76 nowych interfejsów API w bibliotekach klas podstawowych. Obejmują następujące obszary:
  • Aktualizacje obsługi Unicode.
  • Trzy nowe metody Stringobsługi bloków tekstowych (patrz opis JEP 255 powyżej).
  • Klasy java.niomają teraz wartości bezwzględne (w przeciwieństwie do względnych) geti ustalone metody. Zawierają one, podobnie jak podstawowa klasa abstrakcyjna Buffer, metodę slice()pobierania części bufora.
  • Metoda force()klasy MappedByteBufferwymusza zapisanie sekcji bufora w jej pamięci zapasowej.
  • nio.FileSystemdodaje trzy nowe, przeciążone formularze newFileSystem()umożliwiające dostęp do zawartości pliku jako systemu plików.
  • Pojawiła się nowa ciekawa metoda javax.annotation.processing.ProcessingEnvironment. isPreviewEnabled(). Dowiesz się, czy funkcje podglądu są włączone. Jest to interesujące, ponieważ wspomniana powyżej adnotacja @PreviewFeaturenie będzie dostępna do czasu wydania JDK 14.
  • DocumentBuilderFactoryi SAXParserFactoryuzyskaj javax.xml.parserstrzy nowe metody tworzenia instancji uwzględniających przestrzeń nazw.
Materiał powstał w oparciu o artykuł Simona Rittera i oficjalną dokumentację .
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION