Автор оригинала: Sampada Wagde.
1. Обзор
В сентябре 2019 года был выпущен JDK 13, в соответствии с новой каденцией выпуска Java в течение шести месяцев . В этой статье мы рассмотрим новые функции и улучшения, представленные в этой версии.
2. Предварительный просмотр функций разработчика
Java 13 привнесла две новые языковые функции, хотя и в режиме предварительного просмотра . Это означает, что эти функции полностью реализованы для оценки разработчиками, но еще не готовы к производству. Кроме того, они могут быть удалены или сделаны постоянными в будущих выпусках на основе обратной связи.
Нам нужно указать –enable-preview в качестве флага командной строки, чтобы использовать функции предварительного просмотра . Давайте рассмотрим их более подробно.
2.1. Выражения переключения (JEP 354)
Первоначально мы видели выражения переключения в JDK 12 . Java 13/| switch expressions постройте на предыдущей версии, добавив новый оператор yield .
Используя 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); }
Как мы видим, реализовать шаблон strategy с помощью нового переключателя непросто.
2.2. Текстовые блоки (JEP 355)
Вторая функция предварительного просмотра-это текстовые блоки для многострочных строковых s, таких как встроенный JSON, XML, HTML и т. Д.
Ранее, чтобы встроить JSON в наш код, мы объявляли его как String literal:
String JSON_STRING = "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"https://www.%s.com/\"\r\n" + "}";
Теперь давайте напишем тот же JSON, используя String текстовые блоки:
String TEXT_BLOCK_JSON = """ { "name" : "Baeldung", "website" : "https://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() – переводит escape-последовательности, такие как “\\t” в “\t”
- formated() – работает так же, как String::format, но для текстовых блоков
Давайте быстро рассмотрим пример String::formatted :
assertThat(TEXT_BLOCK_JSON.formatted("baeldung").contains("www.baeldung.com")).isTrue(); assertThat(String.format(JSON_STRING,"baeldung").contains("www.baeldung.com")).isTrue();
Поскольку текстовые блоки являются функцией предварительного просмотра и могут быть удалены в будущем выпуске, эти новые методы помечены как устаревшие.
3. Динамические архивы компакт-дисков (JEP 350)
Совместное использование данных классов (CDS) уже некоторое время является важной особенностью виртуальной машины Java HotSpot. Это позволяет совместно использовать метаданные класса в разных JVM, чтобы сократить время запуска и объем памяти . JDK 10 расширил эту возможность, добавив компакт – диски приложений ( APPCD ) – чтобы дать разработчикам возможность включать классы приложений в общий архив. JDK12 дополнительно расширил эту функцию, включив архивы компакт-дисков по умолчанию .
Однако процесс архивирования классов приложений был утомительным. Чтобы создать архивные файлы, разработчики должны были выполнить пробные запуски своих приложений, чтобы сначала создать список классов, а затем сбросить его в архив. После этого этот архив можно будет использовать для обмена метаданными между JVM.
С помощью динамического архивирования JDK 13 упростил этот процесс. Теперь мы можем создать общий архив в момент выхода приложения . Это устранило необходимость в пробных запусках.
Чтобы позволить приложениям создавать динамический общий архив поверх системного архива по умолчанию, нам нужно добавить опцию -XX:ArchiveClassesAtExit и указать имя архива в качестве аргумента:
java -XX:ArchiveClassesAtExit=-cp AppName
Затем мы можем использовать вновь созданный архив для запуска того же приложения с опцией -XX:SharedArchiveFile :
java -XX:SharedArchiveFile=-cp AppName
4. ZGC: Незафиксированная неиспользуемая память (JEP 351)
Сборщик мусора Z был представлен в Java 11 как механизм сбора мусора с низкой задержкой, так что время паузы GC никогда не превышало 10 мс. Однако, в отличие от других виртуальных машин HotSpot, таких как G1 и Shenandoah, он не был оснащен для возврата неиспользуемой памяти кучи в операционную систему. Java 13 добавила эту возможность в ZGC.
Теперь мы получаем сокращение объема памяти наряду с повышением производительности.
Начиная с Java 13, ZGC теперь возвращает незафиксированную память в операционную систему по умолчанию до тех пор , пока не будет достигнут указанный минимальный размер кучи. Если мы не хотим использовать эту функцию, мы можем вернуться к Java 11 путем:
- Использование опции -XX:-Uncommit, или
- Установка равных минимальных ( -Xms ) и максимальных ( -Xmx ) размеров кучи
Кроме того, ZGC теперь имеет максимальный поддерживаемый размер кучи 16 ТБ. Ранее пределом было 4 ТБ.
5. Переопределите устаревший API сокета (JEP 353)
Мы видели сокет ( java.net.Socket и java.net.ServerSocket ) API как неотъемлемая часть Java с момента ее появления. Однако за последние двадцать лет они так и не были модернизированы. Написанные на устаревших языках Java и C, они были громоздкими и трудными в обслуживании.
Java 13 отбросила эту тенденцию и заменила базовую реализацию , чтобы привести API в соответствие с футуристическими потоками пользовательского режима. Вместо PlainSocketImpl интерфейс поставщика теперь указывает на Nio Socket Impl . Эта недавно закодированная реализация основана на той же внутренней инфраструктуре, что и java.nio .
Опять же, у нас есть способ вернуться к использованию PlainSocketImpl . Мы можем запустить JVM с системным свойством -Dgdk.net.use PlainSocketImpl set as true для использования более старой реализации. По умолчанию используется No Socket Impl.
6. Различные Изменения
Помимо перечисленных выше джипов, Java 13 дала нам еще несколько заметных изменений:
- java.nio – метод Файловые системы.newFileSystem(Путь, карта<Строка, ?>) добавлено
- java.time – добавлено новое официальное название японской эпохи
- javax.crypto – поддержка MS Cryptography следующего поколения (CNG)
- javax.security – property jdk.sasl.disabledMechanisms добавлено для отключения механизмов SASL
- javax.xml.crypto – новые Строковые константы, введенные для представления канонических URI XML 1.1
- javax.xml.parsers – добавлены новые методы для создания экземпляров фабрик DOM и SAX с поддержкой пространств имен
- Поддержка Unicode обновлена до версии 12.1
- Добавлена поддержка канонизации основных имен Kerberos и ссылок между областями
Кроме того, несколько API предлагаются для удаления . К ним относятся три метода String , перечисленные выше, и API javax.security.cert|/.
Среди удалений включают инструмент rmic и старые функции из инструмента JavaDoc . Реализации Pre-JDK 1.4 SocketImpl также больше не поддерживаются.
7. Заключение
В этой статье мы рассмотрели все пять предложений по улучшению JDK, реализованных Java 13. Мы также перечислили некоторые другие заметные дополнения и удаления.
Как обычно, исходный код доступен на GitHub .