[Перевод] Что нового в Java 20?

image


Версия Java 20 должна быть выпущена в марте 2023 года, и ожидается, что в ней появится целый ряд изменений и новых функциональных возможностей. Мы подготовили обзор, описывающий, какие JEP с наибольшей вероятностью будут приняты в JDK 20, и какие из них, как мы надеемся, будут приняты в ближайшей перспективе!

Последняя версия JDK (Java Development Kit) 19 была выпущена 20 сентября 2022 года. Следующая версия, Java 20, планируется как релиз без LTS, а следующая версия 21 — как релиз с долгосрочной поддержкой (LTS). Ожидается, что грядущая версия 20 принесет ряд замечательных обновлений, поэтому мы с нетерпением ждем марта, чтобы получить ее в распоряжение!

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

Предложение по расширению (JEP) и процесс составления дорожной карты проекта


Разработка Java Development Kit (JDK) основана на концепции предложений по расширению JDK (JDK Enhancement Proposals, или JEPs). По сути, эти предложения по расширению служат дорожной картой для проектов JDK и всей сопутствующей деятельности по их разработке. Процесс JEP не заменяет рабочий процесс, принятый в сообществе Java, поскольку именно работа на уровне сообщества Java по-прежнему является основным способом утверждения изменений в API и языке.Пожалуй, замысел Oracle при введении JEP в 2010 году заключался в том, чтобы дать возможность участникам OpenJDK вносить идеи для улучшения экосистемы. JEP помогают отслеживать статус разработки функций, предназначенных для внедрения в проект выпуска JDK, а также поддерживать работы, которые не связаны с конкретным релизом.

На момент написания статьи в JEP Index перечислены 437 предложений по улучшению, а также ряд проектов и представленных JEP. Из всех этих предложений по усовершенствованию первые 4 являются мета-JEP:

  • JEP 0 — это список всех размещенных предложений, упомянутых выше.
  • JEP 1 описывает процесс управления (сбор, рассмотрение, определение приоритетов, оценка и запись результатов) предложениями по расширению JDK, улучшению процессов и инфраструктуры.
  • JEP 2 — это шаблон для создания новых JEP.
  • JEP 3 описывает процесс выпуска JDK.


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

image


Можно ознакомиться с текущим списком JEP (черновиков и представленных вариантов) для Java 20 на сайте JEP 0, а также с примечаниями к выпуску раннего доступа для изменений этой версии. Итак, теперь, когда вы понимаете процесс, давайте перейдем непосредственно к тому, какие JEP, как ожидается, войдут в Java 20!

Какие JEP ожидаются в JDK 20?


Шаблоны записи
Представлены в качестве первого превью в JDK 19 и ожидаются в качестве второго превью в JDK 20. Для поддержки навигации и обработки данных шаблоны записей облегчают работу с компонентами записей. Не изменяя синтаксис или семантику шаблонов типов, это предложение расширит возможности подбора шаблонов для более сложных запросов к данным.

Приведенный ниже пример кода (источник) показывает, как элегантно можно получить доступ к компонентам x и y с помощью шаблонов записей, избавившись от типичных обращений к p.x () и p.y ().

if (o instanceof Point(int x, int y)) {
  System.out.println(x+y);
}


Сопоставление по шаблону для операторов switch
Представлен как первый предварительный вариант в JDK 17 и ожидается как четвертый превью в JDK 20. Цель JEP 433 — усилить операторы switch, а также сделать их более легкими для чтения и удобными. В текущих версиях Java в качестве типа выбираемого селектора переключателя могут использоваться целочисленные примитивы, их упакованные версии, перечисления и строки. В новом дополнении переключатели можно использовать для любого типа, а для выбора определенного условия используются шаблоны. Примером такого шаблона является case Triangle t. Этот case будет выполнен, если селектор имеет тип Triangle. Кроме того, условие when может быть использовано в качестве дополнительного фильтра, указывая, какое условие case должно быть выполнено, т. е. для разных треугольников могут быть разные условия. Примером такого условия when может служить условие when t.calculateArea () > 100.

Следующий фрагмент кода (источник) обобщает практику сопоставления по шаблону в операторах switch:

switch (s) {
  case null ->
    { break; }
  case Triangle t
  when t.calculateArea() > 100 ->
    System.out.println("Large triangle");
  default ->
    System.out.println("A shape, possibly a small triangle");
}


Foreign function & memory (FFM) API
API FFM построен на основе разнообразных JEP, которые были объединены — и так появился его первый превью в JDK 19. Ожидается и второй превью в JDK 20. Этот API позволяет вызывать внешние функции для Java-программ для работы с внешним кодом и данными, например, за пределами среды выполнения Java/ При этом данный API лишён недостатков и рисков JNI. Основной целью FFM API является превосходная, чистая модель разработки Java, а также поддержка более широкого спектра моделей внешней памяти.

Виртуальные потоки
Представлены в качестве первого превью в JDK 19 и ожидаются в качестве второго превью в JDK 20. Виртуальные потоки повышают эффективность при написании, поддержке и мониторинге параллельных приложений. Они легковесны, поддерживают масштабируемость по потоку на запрос и могут быть применены с минимальными изменениями в существующем коде. Традиционный поток Java в точности соответствует одному потоку ОС, в то время как виртуальные потоки не привязаны к конкретному потоку ОС. В результате их создание обходится недорого, и вы можете создавать их в таком количестве, в каком потребуется.

Какие JEP мы с нетерпением ждем после JDK 20


Дополнения к системе типов
Следующие изменения в системе типов предоставляют возможности для написания кода с более высокой производительностью или более удобного для чтения и сопровождения.

Примитивные классы
JEP 401 вводит поддержку нового специального класса значений для определения примитивных типов. Использование примитивов позволяет повысить производительность за счет лучшего доступа к памяти и потому, что примитивные операции выполняются в процессоре более эффективно. Благодаря этому обновлению разработчики могут воспользоваться повышенной производительностью примитивов, сохраняя абстракции и другие преимущества, обеспечиваемые при объявлении классов.

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

  • Все поля внутри примитивного класса определяются неявно финальными, то есть они могут быть установлены только в конструкторе или инициализаторе.
  • Кроме того, примитивные классы не могут иметь поля, которые неявно зависят от объявляющего класса.


Примитивные классы объявляются с помощью ключевого слова primitive, то есть:

primitive class Point implements Shape {
   ...
}


Объекты значений
Традиционные объекты Java пподразумевают идентичность, т.е. их расположение в памяти используется для отличия одного объекта от другого. Предложение идентичности во время выполнения ресурсозатратно, и во многих реализациях не используется. В этом представлении объектная модель Java расширена классами значений и объектами значений. Классы значений не содержат идентификаторов, т.е. для них характерны преимущества производительности примитивных типов. Но при работе с ними используются объектно-ориентированные концепции. При использовании функции == на объектах значений для определения равенства объектов используются значения их полей, а не их расположение в памяти. Помните, что все поля классов значений неявно финальные и должны быть заданы в инициализаторе или конструкторе!

Классы значений объявляются с помощью ключевого слова value, т.е:

value class Point implements Shape {
  ...
}


Универсальные дженерики
Это дополнение снимает требование о том, что параметры типа должны быть ссылочными типами, позволяя использовать примитивные классы в качестве параметров типа. Многие существующие реализации дженериков будут работать с этим новым дополнением, т.е. они могут быть инстанцированы с примитивным классом в качестве аргумента типа. Однако следует быть особенно осторожным, если в коде присваивается null, так как примитивные классы будут отказывать, выбрасывая исключение «нулевой указатель».

Шаблоны строк
Для упрощения рутинной композиции строки применяются строковые шаблоны, они же строковые литералы. Они содержат встроенные выражения, которые интерпретируются во время выполнения программы. Добавив в Java новый вид выражения (выражение шаблона строки), JEP 430 упрощает написание кода со строками, включающими значения, вычисляемые во время выполнения. Это позволяет улучшить читабельность, гибкость в определении синтаксиса форматирования и повысить безопасность программ, требующих пользовательский ввод в качестве значений.

Дополнения для многопоточного кода
Если вы работаете с многопоточным кодом, обязательно ознакомьтесь с этими дополнениями, которые предназначены для более удобного чтения многопоточного кода или обеспечивают повышение производительности.

Значения с указанной областью видимости
С расширенными локальными переменными станет проще обмениваться неизменяемыми данными внутри потока и между дочерними потоками в Java. Это обновление сделано для того, чтобы было проще судить о потоке данных, а также для большего удобства использования; повышения надежности. Это делается, чтобы только легитимные вызовы могли получить данные, разделяемые вызывающей стороной. Повышение производительности достигается за счет оптимизации во время выполнения и обработки разделяемых данных как неизменяемых. Хотя это изменение не требует перехода от переменных, локальных в пределах потока, их желательно использовать, особенно при большом количестве виртуальных потоков.

Структурированный параллелизм
С введением API для структурированного параллелизма, обновление JEP 428 позволяет рассматривать различные задачи, выполняемые в отдельных потоках, как отдельные самостоятельные куски работы. Это нововведение должно значительно упростить многопоточное программирование и стимулировать разработчиков к применению параллельного программирования, облегчая обеспечение надежности, поддержки и наблюдаемости кода.

Другие интересные JEP:

  • Последовательные коллекции: добавляет интерфейс SequencedCollection в стандартную библиотеку, предоставляя первую коллекцию, которая определяет порядок следования элементов внутри коллекции.
  • Векторный API: нужен для повышения производительности по сравнению со скалярными вычислениями. Новый API позволяет выполнять векторные вычисления, компилируемые во время выполнения.
  • Асинхронный API трассировки стека: Представляет новый API для асинхронного сбора стектрейсов.
  • Classfile API: Добавляет новый API для замены ASM (или cglib, или другой библиотеки байт-кода), который обеспечит способ чтения, записи и преобразования файлов классов Java.


Заключение: почему мы с нетерпением ждем Java 20


В целом, обновления в Java 20 обещают большую гибкость в создании высокопроизводительного софта. Если вам не терпится попробовать его, ознакомьтесь с ранним доступом, сборками с открытым исходным кодом и отметьте в своем календаре предполагаемую дату выхода — 21 марта 2023 года!

© Habrahabr.ru