Нови функции на Java 13

1. Общ преглед

През септември 2019 г. излезе JDK 13, според новия каданс на Java от шест месеца . В тази статия ще разгледаме новите функции и подобрения, въведени в тази версия.

2. Преглед на функции за разработчици

Java 13 представи две нови езикови функции, макар и в режим на предварителен преглед . Това означава, че тези функции са напълно внедрени за оценка от разработчиците, но все още не са готови за производство. Също така те могат да бъдат премахнати или направени за постоянно в бъдещи версии въз основа на обратна връзка.

Трябва да посочим –enable-preview като флаг на командния ред, за да използваме функциите за визуализация . Нека ги разгледаме задълбочено.

2.1. Превключващи изрази (JEP 354)

Първоначално видяхме изразите на превключватели в JDK 12. Изразите на превключвателите на Java 13 се основават на предишната версия, като добавят нов отчет за добив .

Използвайки yield , вече можем ефективно да върнем стойности от израз на превключвател :

@Test @SuppressWarnings("preview") public void whenSwitchingOnOperationSquareMe_thenWillReturnSquare() { var me = 4; var operation = "squareMe"; var result = switch (operation) { case "doubleMe" -> { yield me * 2; } case "squareMe" -> { yield me * me; } default -> me; }; assertEquals(16, result); }

Както виждаме, сега е лесно да приложите шаблона на стратегията с помощта на новия превключвател.

2.2. Текстови блокове (JEP 355)

Втората функция за предварителен преглед са текстови блокове за многоредови низове , като вградени JSON, XML, HTML и др.

По-рано, за да вградим JSON в нашия код, бихме го декларирали като String литерал:

String JSON_STRING = "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"//www.%s.com/\"\r\n" + "}";

Сега нека напишем същия JSON, като използваме текстови блокове String :

String TEXT_BLOCK_JSON = """ { "name" : "Baeldung", "website" : "//www.%s.com/" } """;

Както е очевидно, няма нужда да избягвате двойни кавички или да добавяте връщане на карета. Използвайки текстови блокове, вграденият JSON е много по-лесен за писане и по-лесен за четене и поддръжка.

Освен това са налични всички функции на String :

@Test public void whenTextBlocks_thenStringOperationsWorkSame() { assertThat(TEXT_BLOCK_JSON.contains("Baeldung")).isTrue(); assertThat(TEXT_BLOCK_JSON.indexOf("www")).isGreaterThan(0); assertThat(TEXT_BLOCK_JSON.length()).isGreaterThan(0); } 

Също така java.lang.String вече има три нови метода за манипулиране на текстови блокове:

  • stripIndent () - имитира компилатора, за да премахне случайно празно пространство
  • translateEscapes () - превежда екраниращи се последователности като “\\ t” в “\ t”
  • formatted () - работи по същия начин като String :: format, но за текстови блокове

Нека да разгледаме набързо пример String :: форматиран :

assertThat(TEXT_BLOCK_JSON.formatted("baeldung").contains("www.baeldung.com")).isTrue(); assertThat(String.format(JSON_STRING,"baeldung").contains("www.baeldung.com")).isTrue(); 

Тъй като текстовите блокове са функция за предварителен преглед и могат да бъдат премахнати в бъдеща версия, тези нови методи са маркирани за оттегляне.

3. Динамични CDS архиви (JEP 350)

Споделянето на данни от клас (CDS) е важна характеристика на Java HotSpot VM от известно време. Тя позволява да се споделят метаданни на класа между различни JVM, за да се намали времето за стартиране и отпечатъка на паметта . JDK 10 разшири тази възможност, като добави CDS на приложения (AppCDS) - за да даде на разработчиците силата да включват класове на приложения в споделения архив. JDK 12 допълнително подобри тази функция, за да включва CDS архиви по подразбиране.

Процесът на архивиране на класове на приложения обаче беше досаден. За да генерират архивни файлове, разработчиците трябваше първо да направят пробни пускове на своите приложения, за да създадат първо списък с класове и след това да го изхвърлят в архив. След това този архив може да се използва за споделяне на метаданни между JVM.

С динамичното архивиране JDK 13 опрости този процес. Сега можем да генерираме споделен архив по времето, когато приложението излиза . Това елиминира необходимостта от пробни пускове.

За да разрешим на приложенията да създават динамичен споделен архив върху системния архив по подразбиране, трябва да добавим опция -XX: ArchiveClassesAtExit и да посочим името на архива като аргумент:

java -XX:ArchiveClassesAtExit= -cp  AppName

След това можем да използваме новосъздадения архив, за да стартираме същото приложение с опция -XX: SharedArchiveFile :

java -XX:SharedArchiveFile= -cp  AppName

4. ZGC: Неангажирана неизползвана памет (JEP 351)

Z Garbage Collector е представен в Java 11 като механизъм за събиране на боклук с ниска латентност, така че времето за пауза на GC никога не надвишава 10 ms. Въпреки това, за разлика от други HotSpot VM GC, като G1 и Shenandoah, той не е оборудван за връщане на неизползваната куп памет в операционната система. Java 13 добави тази възможност към ZGC.

Сега получаваме намален отпечатък на паметта, заедно с подобряване на производителността.

Започвайки с Java 13, ZGC сега по подразбиране връща необвързана памет към операционната система , докато достигне посочения минимален размер на купчината. Ако не искаме да използваме тази функция, можем да се върнем към Java 11 начин, като:

  • Използване на опция -XX: -ZUncommit или
  • Задаване на равни минимални ( -Xms ) и максимални ( -Xmx ) размери на купчината

Освен това ZGC вече има максимален поддържан размер на купчина от 16TB. По-рано 4TB беше ограничението.

5. Реализирайте Legacy Socket API (JEP 353)

От самото начало сме виждали API на Socket ( java.net.Socket и java.net.ServerSocket ) като неразделна част от Java. Те обаче никога не са били модернизирани през последните двадесет години. Написани в наследени Java и C, те са тромави и трудни за поддръжка.

Java 13 bucked this trend and replaced the underlying implementation to align the API with the futuristic user-mode threads. Instead of PlainSocketImpl, the provider interface now points to NioSocketImpl. This newly coded implementation is based on the same internal infrastructure as java.nio.

Again, we do have a way to go back to using PlainSocketImpl. We can start the JVM with the system property -Djdk.net.usePlainSocketImpl set as true to use the older implementation. The default is NioSocketImpl.

6. Miscellaneous Changes

Apart from the JEPs listed above, Java 13 has given us a few more notable changes:

  • java.nio – method FileSystems.newFileSystem(Path, Map) added
  • java.time – new official Japanese era name added
  • javax.crypto – support for MS Cryptography Next Generation (CNG)
  • javax.security – property jdk.sasl.disabledMechanisms added to disable SASL mechanisms
  • javax.xml.crypto – new String constants introduced to represent Canonical XML 1.1 URIs
  • javax.xml.parsers – new methods added to instantiate DOM and SAX factories with namespaces support
  • Unicode support upgraded to version 12.1
  • Support added for Kerberos principal name canonicalization and cross-realm referrals

Освен това се предлагат няколко API за премахване. Те включват трите метода String , изброени по-горе, и API на javax.security.cert .

Сред премахванията са инструментът rmic и стари функции от инструмента JavaDoc. Предварителните реализации на JDK 1.4 SocketImpl също вече не се поддържат.

7. Заключение

В тази статия видяхме всичките пет предложения за подобрение на JDK, изпълнени от Java 13. Изброихме и някои други забележителни допълнения и изтривания.

Както обикновено, изходният код е достъпен в GitHub.