«1. Обзор
Java 14 выпущена 17 марта 2020 г., ровно через шесть месяцев после выхода предыдущей версии в соответствии с новым графиком выпуска Java.
В этом руководстве мы рассмотрим сводку новых и устаревших функций версии 14 языка.
У нас также есть более подробные статьи о Java 14, в которых подробно рассматриваются новые функции.
2. Функции, перенесенные из более ранних версий
Некоторые функции были перенесены в Java 14 из предыдущей версии. Давайте посмотрим на них один за другим.
2.1. Switch Expressions (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. Записи (JEP 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.baeldung.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 в качестве альтернативы уже существующим способам доступа к памяти без кучи — ByteBuffer API и sun.misc.Unsafe API.
Этот 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, в отличие от параллельного сборщика.
Глядя на улучшение производительности, которое он предлагает для запуска одной 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, отсюда и удаление Pack200 Tools and API (JEP 367) — они устарели для удаления в Java 11 и теперь удалены
8. Заключение
В этом руководстве мы рассмотрели различные JEP Java 14.
Всего в этом выпуске языка есть 16 основных функций, включая функции предварительного просмотра, инкубаторы, устаревание и удаление. Мы рассмотрели их все один за другим, а особенности языка с примерами.
Как всегда, исходный код доступен на GitHub.