Перейти к основному содержимому

Новые функции в Java 11

· 7 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

Oracle выпустила Java 11 в сентябре 2018 года, всего через 6 месяцев после предшественницы, версии 10.

Java 11 — это первый выпуск с долгосрочной поддержкой (LTS) после Java 8. Oracle также прекратила поддержку Java 8 в январе 2019 года. Как следствие, многие из нас перейдут на Java 11.

В этом руководстве мы рассмотрим варианты выбора JDK для Java 11. Затем мы рассмотрим новые функции, удаленные функции и улучшения производительности, представленные в Java 11.

2. Oracle против Open JDK

Java 10 был последним бесплатным выпуском Oracle JDK, который мы могли использовать в коммерческих целях без лицензии. Начиная с Java 11, Oracle не предоставляет бесплатную долгосрочную поддержку (LTS).

К счастью, Oracle продолжает предоставлять выпуски Open JDK , которые мы можем скачать и использовать бесплатно.

Помимо Oracle, мы можем рассмотреть и других поставщиков Open JDK .

3. Функции разработчика

Давайте посмотрим на изменения в общих API, а также на некоторые другие функции, полезные для разработчиков.

3.1. Новые строковые методы

В Java 11 к классу String добавлено несколько новых методов `` : isBlank , lines , strip , stripLeading , stripTrailing и repeat .

Давайте посмотрим, как мы можем использовать новые методы для извлечения непустых зачищенных строк из многострочной строки:

String multilineString = "ForEach helps \n \n developers \n explore Java.";
List<String> lines = multilineString.lines()
.filter(line -> !line.isBlank())
.map(String::strip)
.collect(Collectors.toList());
assertThat(lines).containsExactly("ForEach helps", "developers", "explore Java.");

Эти методы могут уменьшить количество шаблонов, используемых при манипулировании строковыми объектами, и избавить нас от необходимости импортировать библиотеки.

В случае методов полосы они обеспечивают функциональность, аналогичную более знакомому методу обрезки ; однако с более точным управлением и поддержкой Unicode.

3.2. Новые файловые методы

Кроме того, теперь стало проще читать и записывать String из файлов.

Мы можем использовать новые статические методы readString и writeString из класса Files :

Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
String fileContent = Files.readString(filePath);
assertThat(fileContent).isEqualTo("Sample text");

3.3. Коллекция в массив

Интерфейс java.util.Collection содержит новый метод toArray по умолчанию , который принимает аргумент IntFunction .

Это упрощает создание массива нужного типа из коллекции:

List sampleList = Arrays.asList("Java", "Kotlin");
String[] sampleArray = sampleList.toArray(String[]::new);
assertThat(sampleArray).containsExactly("Java", "Kotlin");

3.4. Непредикатный метод

В интерфейс Predicate добавлен статический метод not . Мы можем использовать его для отрицания существующего предиката, подобно методу отрицания :

List<String> sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
List withoutBlanks = sampleList.stream()
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toList());
assertThat(withoutBlanks).containsExactly("Java", "Kotlin");

Хотя not(isBlank) читается более естественно, чем isBlank .negate() , большим преимуществом является то, что мы также можем использовать not со ссылками на методы, например not(String:isBlank) .

3.5. Синтаксис локальной переменной для Lambda

В Java 11 была добавлена поддержка использования синтаксиса локальных переменных ( ключевое слово var ) в параметрах лямбда.

Мы можем использовать эту функцию для применения модификаторов к нашим локальным переменным, например, для определения аннотации типа:

List<String> sampleList = Arrays.asList("Java", "Kotlin");
String resultString = sampleList.stream()
.map((@Nonnull var x) -> x.toUpperCase())
.collect(Collectors.joining(", "));
assertThat(resultString).isEqualTo("JAVA, KOTLIN");

3.6. HTTP-клиент

Новый HTTP-клиент из пакета java.net.http был представлен в Java 9. Теперь он стал стандартной функцией в Java 11.

Новый HTTP API повышает общую производительность и обеспечивает поддержку как HTTP/1.1, так и HTTP/2:

HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:" + port))
.build();
HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
assertThat(httpResponse.body()).isEqualTo("Hello from the server!");

3.7. Контроль доступа на основе гнезда

Java 11 вводит понятие соплеменников и связанных с ними правил доступа в JVM.

Вложение классов в Java подразумевает как внешний/основной класс, так и все его вложенные классы:

assertThat(MainClass.class.isNestmateOf(MainClass.NestedClass.class)).isTrue();

Вложенные классы связаны с атрибутом NestMembers , а внешний класс связан с атрибутом NestHost :

assertThat(MainClass.NestedClass.class.getNestHost()).isEqualTo(MainClass.class);

Правила доступа JVM разрешают доступ к закрытым членам между соседями; однако в предыдущих версиях Java API отражения запрещал такой же доступ.

Java 11 устраняет эту проблему и предоставляет средства для запроса новых атрибутов файла класса с использованием API отражения:

Set<String> nestedMembers = Arrays.stream(MainClass.NestedClass.class.getNestMembers())
.map(Class::getName)
.collect(Collectors.toSet());
assertThat(nestedMembers).contains(MainClass.class.getName(), MainClass.NestedClass.class.getName());

3.8. Запуск Java-файлов

Основное изменение в этой версии заключается в том, что нам больше не нужно явно компилировать исходные файлы Java с помощью javac :

$ javac HelloWorld.java
$ java HelloWorld
Hello Java 8!

Вместо этого мы можем напрямую запустить файл с помощью команды java :

$ java HelloWorld.java
Hello Java 11!

4. Повышение производительности

Теперь давайте взглянем на пару новых функций, основной целью которых является повышение производительности.

4.1. Динамические константы файла класса

Формат файла классов Java расширен для поддержки новой формы пула констант с именем CONSTANT_Dynamic .

Загрузка нового пула констант делегирует создание методу начальной загрузки, точно так же, как связывание сайта вызова invokedynamic делегирует связь с методом начальной загрузки.

Эта функция повышает производительность и предназначена для разработчиков языков и разработчиков компиляторов.

4.2. Улучшенная внутренняя структура Aarch64

Java 11 оптимизирует существующие встроенные функции строк и массивов на процессорах ARM64 или AArch64. Кроме того, реализованы новые встроенные функции для методов sin, cos и log java.lang.Math .

Мы используем встроенную функцию, как и любую другую; однако встроенная функция обрабатывается компилятором особым образом. Он использует код сборки для конкретной архитектуры ЦП для повышения производительности.

4.3. Сборщик мусора без операций

Новый сборщик мусора под названием Epsilon доступен для использования в Java 11 в качестве экспериментальной функции.

Он называется No-Op (без операций), потому что он выделяет память, но фактически не собирает мусор. Таким образом, Epsilon применим для моделирования ошибок нехватки памяти.

Очевидно, что Epsilon не подходит для типичного производственного Java-приложения; однако есть несколько конкретных случаев использования, в которых это может быть полезно:

  • Тестирование производительности
  • Тестирование нагрузки на память
  • Тестирование интерфейса ВМ и
  • Чрезвычайно кратковременные работы

Чтобы включить его, используйте флаг -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC .

4.4. Бортовой регистратор

Java Flight Recorder (JFR) теперь является открытым исходным кодом в Open JDK , тогда как раньше он был коммерческим продуктом в Oracle JDK. JFR — это инструмент профилирования, который мы можем использовать для сбора данных диагностики и профилирования из работающего приложения Java.

Чтобы начать 120-секундную запись JFR, мы можем использовать следующий параметр:

-XX:StartFlightRecording=duration=120s,settings=profile,filename=java-demo-app.jfr

Мы можем использовать JFR в производственной среде, так как его накладные расходы на производительность обычно не превышают 1%. По истечении времени мы можем получить доступ к записанным данным, сохраненным в файле JFR; однако для анализа и визуализации данных нам необходимо использовать другой инструмент под названием JDK Mission Control (JMC).

5. Удаленные и устаревшие модули

По мере развития Java мы больше не можем использовать какие-либо из удаленных функций и должны прекратить использование любых устаревших функций. Давайте кратко рассмотрим наиболее заметные из них.

5.1. Java EE и CORBA

Отдельные версии технологий Java EE доступны на сторонних сайтах; поэтому для Java SE нет необходимости их включать.

В Java 9 уже объявлены устаревшими некоторые модули Java EE и CORBA. В выпуске 11 теперь полностью удалено:

  • API Java для веб-служб на основе XML (java.xml.ws )
  • Архитектура Java для привязки XML (java.xml.bind )
  • Платформа активации JavaBeans (java.activation )
  • Общие аннотации (java.xml.ws.annotation )
  • Общая архитектура брокера объектных запросов (java.corba)
  • API JavaTransaction (java.transaction )

5.2. JMC и JavaFX

JDK Mission Control (JMC) больше не входит в состав JDK. Автономная версия JMC теперь доступна для отдельной загрузки.

То же самое верно и для модулей JavaFX ; JavaFX будет доступен в виде отдельного набора модулей вне JDK.

5.3. Устаревшие модули

Кроме того, в Java 11 устарели следующие модули:

  • Движок Nashorn JavaScript, включая инструмент JJS
  • Схема сжатия Pack200 для файлов JAR

6. Прочие изменения

Java 11 представила еще несколько изменений, о которых важно упомянуть:

  • Новые реализации шифров ChaCha20 и ChaCha20-Poly1305 заменяют небезопасный потоковый шифр RC4.
  • Поддержка соглашения о криптографическом ключе с Curve25519 и Curve448 заменяет существующую схему ECDH.
  • Обновление Transport Layer Security (TLS) до версии 1.3 обеспечивает повышение безопасности и производительности.
  • Представлен сборщик мусора с малой задержкой, ZGC, в качестве экспериментальной функции с коротким временем паузы.
  • Поддержка Unicode 10 приносит больше символов, символов и смайликов.

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

В этой статье мы рассмотрели некоторые новые функции Java 11.

Мы рассмотрели различия между Oracle и Open JDK. Мы также рассмотрели изменения API, а также другие полезные функции разработки, улучшения производительности и удаленные или устаревшие модули.

Как всегда, исходный код доступен на GitHub .