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

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

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

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

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

ANDROMEDA

1. Обзор

Java 14 выпущена 17 марта 2020 г., ровно через шесть месяцев после предыдущей версии в соответствии с новым графиком выпуска Java.

В этом руководстве мы рассмотрим сводку новых и устаревших функций версии 14 языка .

У нас также есть более подробные статьи о Java 14 , в которых подробно рассматриваются новые функции.

2. Функции, перенесенные из более ранних версий

Некоторые функции были перенесены в Java 14 из предыдущей версии. Давайте посмотрим на них один за другим.

2.1. Выражения переключения ( JEP 361 )

Впервые они были представлены в качестве функции предварительного просмотра в JDK 12, и даже в Java 13 они остались только в качестве функций предварительного просмотра. Но теперь выражения переключения были стандартизированы, так что они являются неотъемлемой частью комплекта разработки .

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

В качестве простого примера давайте рассмотрим сценарий, в котором мы определяем дни недели как будни или выходные.

До этого улучшения мы бы написали это так:

boolean isTodayHoliday;
switch (day) {
case "MONDAY":
case "TUESDAY":
case "WEDNESDAY":
case "THURSDAY":
case "FRIDAY":
isTodayHoliday = false;
break;
case "SATURDAY":
case "SUNDAY":
isTodayHoliday = true;
break;
default:
throw new IllegalArgumentException("What's a " + day);
}

С помощью выражений switch мы можем написать то же самое более лаконично:

boolean isTodayHoliday = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> false;
case "SATURDAY", "SUNDAY" -> true;
default -> throw new IllegalArgumentException("What's a " + day);
};

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

Текстовые блоки продолжают свой путь к массовому обновлению и по-прежнему доступны в качестве функций предварительного просмотра.

В дополнение к возможностям JDK 13, позволяющим упростить использование многострочных строк, во втором предварительном просмотре текстовые блоки теперь имеют две новые escape-последовательности :

  • \: для обозначения конца строки, чтобы не вводился новый символ строки
  • \s: для указания одного пробела

Например:

String multiline = "A quick brown fox jumps over a lazy dog; the lazy dog howls loudly.";

теперь можно записать как:

String multiline = """
A quick brown fox jumps over a lazy dog; \
the lazy dog howls loudly.""";

Это улучшает читаемость предложения для человеческого глаза, но не добавляет новую строку после собаки; .

3. Новые функции предварительного просмотра

3.1. Сопоставление с образцом для instanceof ( JEP 305 ) ``

В JDK 14 введено сопоставление с образцом для instanceof с целью исключения шаблонного кода и облегчения жизни разработчика.

Чтобы понять это, давайте рассмотрим простой пример.

Перед этой функцией мы писали:

if (obj instanceof String) {
String str = (String) obj;
int len = str.length();
// ...
}

Теперь нам не нужно столько кода, чтобы начать использовать obj , как String:

if (obj instanceof String str) {
int len = str.length();
// ...
}

В будущих версиях Java будет реализовано сопоставление с образцом для других конструкций, таких как переключатель .

3.2. Записи ( 359 японских японских японских юаней )

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

Например, модель данных для пользователя с идентификатором и паролем может быть просто определена как:

public record User(int id, String password) { };

Как мы видим, здесь мы используем новое ключевое слово, запись . Это простое объявление автоматически добавит для нас конструктор, геттеры, методы equals , hashCode и toString . **** ``

Давайте посмотрим на это в действии с помощью JUnit:

private User user1 = new User(0, "UserOne");

@Test
public void givenRecord_whenObjInitialized_thenValuesCanBeFetchedWithGetters() {
assertEquals(0, user1.id());
assertEquals("UserOne", user1.password());
}

@Test
public void whenRecord_thenEqualsImplemented() {
User user2 = user1;
assertTrue(user1, user2);
}

@Test
public void whenRecord_thenToStringImplemented() {
assertTrue(user1.toString().contains("UserOne"));
}

4. Новые производственные возможности

Наряду с двумя новыми функциями предварительного просмотра Java 14 также предоставила конкретную готовую к работе.

4.1. Полезные исключения NullPointerException ( JEP 358 )

Раньше трассировка стека для исключения NullPointerException не могла рассказать ничего особенного, за исключением того, что какое-то значение было нулевым в данной строке в данном файле.

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

Теперь Java упростила эту задачу , добавив возможность указать, что именно было нулевым в данной строке кода .

Например, рассмотрим этот простой фрагмент:

int[] arr = null;
arr[0] = 1;

Раньше при запуске этого кода в журнале было написано:

Exception in thread "main" java.lang.NullPointerException
at com.foreach.MyClass.main(MyClass.java:27)

Но теперь, учитывая тот же сценарий, журнал может сказать:

java.lang.NullPointerException: Cannot store to int array because "a" is null

Как видим, теперь мы точно знаем, какая переменная вызвала исключение.

5. Особенности инкубации

Это неокончательные API и инструменты, которые разрабатывает команда Java и предоставляет нам для экспериментов. Они отличаются от функций предварительного просмотра и предоставляются в виде отдельных модулей в пакете jdk.incubator .

5.1. API доступа к внешней памяти ( JEP 370 )

Это новый API , позволяющий программам Java безопасно и эффективно обращаться к внешней памяти, например к собственной памяти, за пределами кучи.

Многие библиотеки Java, такие как mapDB и memcached , имеют доступ к внешней памяти, и настало время, чтобы Java API сам предложил более чистое решение. С этим намерением команда придумала этот JEP в качестве альтернативы уже существующим способам доступа к памяти без кучи — API ByteBuffer и API sun.misc.Unsafe .

Этот API, основанный на трех основных абстракциях MemorySegment , MemoryAddress и MemoryLayout , представляет собой безопасный способ доступа как к куче, так и к памяти без кучи.

5.2. Инструмент для упаковки ( JEP 343 )

Традиционно для доставки кода Java разработчик приложения просто отправлял файл JAR, который пользователь должен был запустить в своей собственной JVM.

Однако пользователи скорее ожидали, что установщик дважды щелкнет, чтобы установить пакет на свои собственные платформы, такие как Windows или macOS.

Этот JEP направлен именно на это. Разработчики могут использовать jlink , чтобы сжать JDK до минимума необходимых модулей, а затем использовать этот инструмент упаковки для создания облегченного образа, который можно установить как exe в Windows или dmg в macOS.

6. Возможности JVM/HotSpot

6.1. ZGC для Windows ( JEP 365 ) и macOS ( JEP 364 ) — экспериментальный

Z Garbage Collector , масштабируемый сборщик мусора с малой задержкой, впервые был представлен в Java 11 в качестве экспериментальной функции. Но изначально единственной поддерживаемой платформой была Linux/x64.

Получив положительные отзывы о ZGC для Linux, Java 14 также перенесла поддержку на Windows и macOS . Хотя это все еще экспериментальная функция, все готово к работе в следующем выпуске JDK .

6.2. Выделение памяти с учетом NUMA для G1 ( JEP 345 )

Неоднородный доступ к памяти (NUMA) до сих пор не был реализован для сборщика мусора G1, в отличие от сборщика Parallel.

Глядя на улучшение производительности, которое он предлагает для запуска одной JVM на нескольких сокетах, этот JEP был введен, чтобы сборщик G1 также поддерживал NUMA .

На данный момент нет планов тиражировать то же самое для других сборщиков HotSpot.

6.3. Потоковая передача событий JFR ( JEP 349 )

Благодаря этому усовершенствованию данные бортового самописца JDK теперь доступны для постоянного мониторинга. Это включает в себя модификации пакета jdk.jfr.consumer , чтобы пользователи могли напрямую читать или передавать записанные данные.

7. Устаревшие или удаленные функции

В Java 14 устарели несколько функций:

  • Порты Solaris и SPARC ( JEP 362 ) — потому что эта операционная система Unix и процессор RISC не находятся в активной разработке последние несколько лет.
  • Комбинация ParallelScavenge + SerialOld GC ( JEP 366 ) — поскольку это редко используемая комбинация алгоритмов GC, которая требует значительных усилий по обслуживанию.

Также есть пара удалений:

  • Concurrent Mark Sweep (CMS) Garbage Collector ( JEP 363 ) — устарел в Java 9, этот сборщик мусора был заменен G1 в качестве сборщика мусора по умолчанию. Кроме того, сейчас можно использовать другие более эффективные альтернативы, такие как ZGC и Shenandoah, поэтому удаление
  • Инструменты и API Pack200 ( JEP 367 ) - они устарели для удаления в Java 11 и теперь удалены .

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

В этом руководстве мы рассмотрели различные JEP Java 14.

Всего в этом выпуске языка есть 16 основных функций , включая функции предварительного просмотра, инкубаторы, устаревание и удаление. Мы рассмотрели их все один за другим, а особенности языка с примерами.

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