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

Java 19 что нового

  • автор:

Вышла Java 19

Вышла общедоступная версия Java 19. В этот релиз попало более двух тысяч закрытых задач и 7 JEP’ов. Release Notes можно посмотреть здесь. Изменения API – здесь.

Ссылки на скачивание:

Вот список JEP’ов, которые попали в Java 19

Паттерн-матчинг для switch (Third Preview) (JEP 427)

Паттерн-матчинг для switch , который появился в Java 17 в режиме preview и остался на второе preview в Java 18, всё ещё остаётся в этом статусе. Это первый случай в Java, когда языковой конструкции не хватило двух релизов, чтобы стать стабильной: ранее все конструкции укладывались в два preview.

В этом релизе в паттерн-матчинг было внесено два главных изменения.

Во-первых, охранные паттерны && были заменены на условия when :

// --enable-preview --release 18: switch (obj) < case Integer x && x >0 -> . ; default -> . ; >
// --enable-preview --release 19: switch (obj) < case Integer x when x >0 -> . ; default -> . ; >

О мотивации такого изменения можно прочитать в рассылке проекта Amber.

Во-вторых, было изменено поведение матчинга null . Теперь null матчится только в ветке case null и больше ни в каких других, включая тотальных:

// --enable-preview --release 18: Object obj = null; switch (obj) < case Object x ->. ; // matches because total pattern >
// --enable-preview --release 19: Object obj = null; switch (obj) < case Object x ->. ; // NPE >
// --enable-preview --release 19: Object obj = null; switch (obj) < case null ->. ; // OK case Object x -> . ; >

Про причины такого изменения можно также прочитать в рассылке.

Паттерны записей (Preview) (JEP 405)

Паттерн-матчинг дополнился новым видом паттерна: паттерн записей.

Раньше для паттерн-матчинга записей был доступен только паттерн по типу с дальнейшим ручным извлечением компонентов:

record Point(int x, int y) <> static void printSum(Object o) < if (o instanceof Point p) < int x = p.x(); int y = p.y(); System.out.println(x + y); >>

С паттернами записей код становится существенно компактнее:

static void printSum(Object o) < if (o instanceof Point(int x, int y)) < System.out.println(x + y); >>

Паттерны записей могут быть вложенными:

record Point(int x, int y) <> enum Color < RED, GREEN, BLUE >record ColoredPoint(Point p, Color c) <> static void printCoordinatesAndColor(ColoredPoint cp) < if (cp instanceof ColoredPoint(Point(var x, var y), var c)) < System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("color java">static void printObject(Object obj) < if (obj instanceof Point(var x, var y) p) < System.out.println("point = " + p); System.out.println("x = " + x); System.out.println("y java">static void printObject(Object obj) < switch (obj) < case Point(var x, var y) when x >0 && y > 0 -> System.out.println("Positive point: x = " + x + ", y Point: x = " + x + ", y Other"); > >

Virtual Threads (Preview) (JEP 425)

В Java появились виртуальные потоки в режиме preview.

Виртуальные потоки, в отличие от потоков операционной системы, являются легковесными и могут создаваться в огромном количестве (миллионы экземпляров). Это свойство должно значительно облегчить написание конкурентных программ, поскольку позволит применять простой подход «один запрос – один поток» и не прибегать к более сложному асинхронному программированию. При этом миграция на виртуальные потоки уже существующего кода должна быть максимально простой, потому что виртуальные потоки являются экземплярами существующего класса java.lang.Thread , а значит, большую часть существующего кода не придётся переписывать.

Виртуальные потоки реализованы поверх обычных потоков и существуют только для JVM, но не для операционной системы (отсюда и название «виртуальные»). Поток, на котором в данный момент работает виртуальный поток, называется потоком-носителем. Если потоки платформы полагаются на планировщик операционной системы, то планировщиком для виртуальных потоков является ForkJoinPool . Когда виртуальный поток блокируется на некоторой блокирующей операции, то он размонтируется от своего потока-носителя, что позволяет потоку-носителю примонтировать другой виртуальный поток и продолжить работу. Такой режим работы и малый размер виртуальных потоков позволяет им очень хорошо масштабироваться. Однако на данный момент есть два исключения: synchronized блоки и JNI. При их выполнении виртуальный поток не может быть размонтирован, поскольку он привязан к своему потоку-носителю. Такое ограничение может препятствовать масштабированию. Поэтому при желании максимально использовать потенциал виртуальных потоков рекомендуется избегать synchronized блоки и операции JNI, которые выполняются часто или занимают длительное время.

Для создания виртуальных потоков и работы с ними появилось следующее API:

  • Thread.Builder – билдер потоков. Например, виртуальный поток можно создать путём вызова Thread.ofVirtual().name(«name»).unstarted(runnable) .
  • Thread.startVirtualThread(Runnable) – создаёт и сразу же запускает виртуальный поток.
  • Thread.isVirtual() – проверяет, является ли поток виртуальным.
  • Executors.newVirtualThreadPerTaskExecutor() – возвращает исполнитель, который создаёт новый виртуальный поток на каждую задачу.

Для виртуальных потоков также добавилась поддержка в дебаггере, JVM TI и Java Flight Recorder.

Виртуальные потоки разрабатываются с 2017 года в рамках проекта Loom.

Structured Concurrency (Incubator) (JEP 428)

Ещё одним результатом работы над проектом Loom стало добавление в Java нового API для Structured Concurrency.

Structured Concurrency – это подход многопоточного программирования, который заимствует принципы из однопоточного структурного программирования. Главная идея такого подхода заключается в следующем: если задача расщепляется на несколько конкурентных подзадач, то эти подзадачи воссоединяются в блоке кода главной задачи. Все подзадачи логически сгруппированы и организованы в иерархию. Каждая подзадача ограничена по времени жизни областью видимости блока кода главной задачи.

В центре нового API класс StructuredTaskScope . Пример использования StructuredTaskScope , где показана задача, которая параллельно запускает две подзадачи и дожидается результата их выполнения:

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) < Futureuser = scope.fork(() -> findUser()); Future order = scope.fork(() -> fetchOrder()); scope.join(); // Join both forks scope.throwIfFailed(); // . and propagate errors return new Response(user.resultNow(), order.resultNow()); >

Может показаться, что в точности аналогичный код можно было бы написать с использованием ExecutorService и submit() , но у StructuredTaskScope есть несколько принципиальных отличий, которые делают код безопаснее:

  • Время жизни всех потоков подзадач ограничено областью видимости блока try-with-resources . Метод close() гарантированно не завершится, пока не завершатся все подзадачи.
  • Если одна из операций findUser() и fetchOrder() завершается ошибкой, то другая операция отменяется автоматически, если ещё не завершена (в случае политики ShutdownOnFailure , возможны другие).
  • Если главный поток прерывается в процессе ожидания join() , то обе операции findUser() и fetchOrder() отменяются.
  • В дампе потоков будет видна иерархия: потоки, выполняющие findUser() и fetchOrder() , будут отображаться как дочерние для главного потока.

Новое API должно облегчить написание многопоточных программ благодаря знакомому структурному подходу. Пока API имеет инкубационный статус, оно будет находиться в модуле jdk.incubator.concurrent и одноимённом пакете.

Foreign Function & Memory API (Preview) (JEP 424)

Foreign Function & Memory API, которое было в инкубационном статусе в Java 17 и Java 18, теперь стало Preview API. Оно находится в пакете java.lang.foreign .

Vector API (Fourth Incubator) (JEP 426)

Векторное API, которое уже было в инкубационном статусе три релиза (Java 16, Java 17, Java 18), продолжает в нём находиться. Пока API не выйдет из инкубационного статуса, оно будет находиться в модуле jdk.incubator.vector .

Linux/RISC-V Port (JEP 422)

JDK теперь официально портирован под архитектуру Linux/RISC-V.

Заключение

Java 19 не является LTS-релизом и будет получать обновления от Oracle только в течение полугода (до марта 2023 года). Однако Azul обещает выпускать обновления Zulu как минимум до марта 2025 года (2.5 года).

Руководство по возможностям языка Java версий 8-19

Вы можете использовать это руководство для получения практической информации о том, как найти и установить последнюю версию Java, понять различия между дистрибутивами Java (Adoptium, AdoptOpenJdk, OpenJDK, OracleJDK и т. д.), а также получить обзор функций языка Java, включая версии 8–19.

Примечание переводчика: 11 апреля 2021 г. был опубликован перевод Руководство по возможностям Java версий 8-16.

Вашему вниманию предлагается обновленная версия руководства от 28 октября 2022 г.

Практическая информация

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

TL; DR Мне нужна только ссылка для скачивания, и я знаю обо всем остальном. Куда мне следует идти?

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

TL;DR (англ. too long; didn’t read — слишком длинно, не читал)

Какая последняя версия Java?

По состоянию на сентябрь 2022 года Java 19 является последней выпущенной версией Java.

В марте 2023 года за ней последует Java 20. Последней версией Java с долгосрочной поддержкой (LTS) является Java 17, выпущенная в сентябре 2021 года.

Какую версию Java следует использовать?

Новые версии Java теперь выходят каждые 6 месяцев. Таким образом, Java 20 запланирована на март 2023 года, Java 21 — на сентябрь 2023 года и так далее. В прошлом циклы выпуска Java были намного длиннее, до 3–5 лет. Данный график демонстрирует, это:

С таким количеством выходящих новых версий имеются следующие основные сценарии использования:

  • Унаследованные проекты в компаниях часто застряли на использовании Java 8 (см. раздел «Почему компании все еще застряли на Java 8?» ниже). Следовательно, вы также будете вынуждены использовать Java 8.
  • Некоторые устаревшие проекты даже застряли на Java 1.5 (выпущен в 2004 г.) или 1.6 (выпущен в 2006 г.) — извините, друзья, я вам сочувствую!
  • Если вы следите за тем, чтобы использовать самые последние IDE, фреймворки и инструменты сборки и начинаете новый проект, вы можете без колебаний использовать Java 17 (LTS) или даже последнюю версию Java 19.
  • Есть особая область разработки Android, где версия Java в основном застряла на Java 7 с определенным набором возможностей Java 8. Или вы переходите на использование языка программирования Kotlin.

Почему компании все еще застряли на Java 8?

Существует целый ряд причин, по которым компании все еще придерживаются Java 8. Вот некоторые из них:

  • Инструменты сборки (Maven, Gradle и т. д.) и некоторые библиотеки изначально содержали ошибки с версиями Java > 8 и нуждались в обновлениях. Например, некоторые инструменты сборки, такие как Maven, выводили предупреждения о «рефлективном доступе» при сборке Java‑проектов, которые просто «кажутся не готовыми», даже если сборки в порядке.
  • Вплоть до Java 8 вы в практически использовали сборки Oracle JDK, и вам не нужно было заботиться о лицензировании. Однако в 2019 году Oracle изменила схему лицензирования, что привело к тому, что Интернет сошел с ума от множества статей, в которых говорилось, что «Java больше не является бесплатной», — и последовала изрядная путаница. Однако на самом деле это не является проблемой, о которой вы узнаете в разделе «Дистрибутивы Java» этого руководства.
  • Некоторые компании придерживаются политики использования только LTS‑версий и полагаются на поставщиков своих ОС, которые должны предоставить им эти сборки, что требует времени.

Подводя итог: у вас есть сочетание практических вопросов (обновление ваших инструментов, библиотек, фреймворков) и политических проблем.

Почему некоторые версии Java, например 8, также называются 1.8?

В версиях Java до 9 просто была другая схема именования. Так, Java 8 также может называться 1.8, Java 5 может называться 1.5 и т. д. Когда вы вводили команду java ‑version , с этими версиями вы получали следующий результат:

c:\Program Files\Java\jdk1.8.0_191\bin>java -version java version "1.8.0_191" (1) Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

Это просто означает Java 8. С переходом к основанным на времени выпускам с Java 9 схема именования также изменилась, и версии Java больше не имеют префикса 1.x. Теперь номер версии выглядит следующим образом:

c:\Program Files\Java\jdk11\bin>java -version openjdk version "11" 2018-09-25 (1) OpenJDK Runtime Environment 18.9 (build 11+28) OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

В чем разница между версиями Java? Должен ли я изучать какую-то конкретную версию?

Придя из других языков программирования с большими перерывами между выпусками, как, например, Python 2–3, вы можете задаться вопросом, применимо ли то же самое к Java.

В этом отношении Java является особенной, поскольку она имеет полную обратную совместимость. Это означает, что ваша программа на Java 5 или 8 гарантированно будет работать на виртуальной машине Java 8–19 — за некоторыми исключениями, о которых вам пока не нужно беспокоиться.

Очевидно, что это не работает, наоборот, скажем, ваша программа полагается на функции Java 19, которые просто недоступны в Java 8 JVM.

Это означает несколько вещей:

  • Вы не просто «выучите» конкретную версию Java, например 12.
  • Скорее, вы получите хорошую основу для всех языковых функций вплоть до Java 8. Это послужит хорошей базой.
  • А затем, из такого руководства, как это, вы можете узнать, какие дополнительные возможности появились в Java 9–19, и будете использовать их всегда, когда это возможно.

Каковы примеры этих новых возможностей новых версий Java?

Посмотрите раздел «Возможности Java 8–19» ниже.

Но, как правило: старые, более длинные циклы выпуска (3–5 лет, вплоть до Java 8) означали большое количество новых функций в каждом выпуске.

Шестимесячный цикл выпуска означает гораздо меньшее количество функций на один выпуск, поэтому вы можете быстро освоить языковые возможности Java 9–19.

В чем разница между JRE и JDK?

До сих пор мы говорили только о «Java». Но что именно означает «Java»?

Во‑первых, необходимо различать JRE (Java Runtime Environment) и JDK (Java Development Kit).

Исторически сложилось так, что вы загружали только JRE, если вас интересовал только запуск программ на Java. JRE включает, помимо прочего, виртуальную машину Java (JVM) и инструмент командной строки «java».

Для разработки новых программ на Java необходимо было загрузить JDK. JDK включает в себя все, что есть в JRE, а также компилятор javac и несколько других инструментов, таких как javadoc (генератор документации Java) и jdb (отладчик Java).

Теперь, почему я говорю в прошедшем времени?

Вплоть до Java 8 веб‑сайт Oracle предлагал JRE и JDK в качестве отдельных файлов загрузки, хотя JDK также всегда включал JRE в отдельной папке. В Java 9 это различие практически исчезло, и вы всегда загружаете JDK. Структура каталогов JDK также изменилась, так как в ней больше не было явной папки JRE.

Поэтому, несмотря на то что некоторые дистрибутивы (см. Раздел «Дистрибутивы Java») по‑прежнему предлагают отдельную загрузку JRE, похоже, наметилась тенденция предлагать только JDK. Следовательно, с этого момента мы будем использовать Java и JDK как взаимозаменяемые понятия.

Как установить Java или JDK?

Пока не обращайте внимания на образы Java‑Docker, оболочки.msi или пакеты для конкретной платформы. В конце концов, Java — это просто ZIP‑файл, ни больше, ни меньше.

Поэтому все, что вам нужно сделать, чтобы установить Java на свой компьютер, — это разархивировать файл jdk‑.zip. Для этого даже не нужны права администратора.

Ваш распакованный файл Java будет выглядеть следующим образом:

Directory C:\dev\jdk-11 12.11.2019 19:24 . 12.11.2019 19:24 .. 12.11.2019 19:23 bin 12.11.2019 19:23 conf 12.11.2019 19:24 include 12.11.2019 19:24 jmods 22.08.2018 19:18 legal 12.11.2019 19:24 lib 12.11.2019 19:23 1.238 release

Магия происходит в каталоге /bin, который в Windows выглядит следующим образом:

Directory C:\dev\jdk-11\bin . 12.11.2019 19:23 272.736 java.exe . 12.11.2019 19:23 20.832 javac.exe . 

Поэтому все, что вам нужно сделать, это разархивировать этот файл и поместить каталог /bin в переменную PATH, чтобы вы могли вызывать команду java из любого места.

Если вам интересно, установщики с графическим интерфейсом, такие как Oracle или Adoptium, выполняет для вас распаковку и изменение переменной PATH, вот и все.

Чтобы убедиться, что вы правильно установили Java, вы можете просто выполнить команду java ‑version. Если результат выглядит так, как показано ниже, вы готовы начать разработку.

openjdk version "11" 2018-09-25 OpenJDK Runtime Environment 18.9 (build 11+28) OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

Теперь остался один вопрос: откуда вам взять этот ZIP‑файл с Java? Что подводит нас к теме дистрибутивов.

Дистрибутивы Java

Есть множество сайтов, предлагающих скачать Java (читай: JDK), и непонятно, «кто что предлагает и с какой лицензией». Этот раздел прольет на это некоторый свет.

Проект OpenJDK

Что касается исходного кода Java (читайте: исходного кода для вашего JRE / JDK), существует только один, находящийся на сайте проекта OpenJDK.

Однако это всего лишь исходный код, а не распространяемая сборка (представьте: ваш файл.zip со скомпилированной командой java для вашей конкретной операционной системы). Теоретически мы с вами могли бы создать сборку из этого исходного кода, назвать ее, скажем, MarcoJDK и начать ее распространять. Но нашему дистрибутиву не хватило бы сертификации, чтобы легально называть этот дистрибутив совместимым с Java SE.

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

И хотя поставщики не могут, скажем, удалить метод из класса String до выпуска новой сборки Java, они могут добавить брэндинг (ура!) или добавить некоторые другие утилиты (например, CLI), которые они считают полезными. Но в остальном исходный код одинаков для всех дистрибутивов Java.

Сборки OpenJDK (от Oracle) и OracleJDK

Одним из производителей, который собирает Java из исходников, является Oracle. Это приводит к появлению двух разных дистрибутивов Java, что поначалу может казаться очень запутанными.

  1. Сборки OpenJDK от Oracle (!). Эти сборки бесплатны и не брендированы, но Oracle не будет выпускать обновления для более старых версий, скажем, Java 15, как только выйдет Java 16.
  2. OracleJDK, которая является фирменной, коммерческой сборкой, выпускаемая начиная с изменения лицензии в 2019 году. Это означает, что ее можно использовать бесплатно во время разработки, но вам придется заплатить Oracle при ее использовании в производственной среде. За это вы получаете более длительную поддержку, то есть все обновления дистрибутива и номер телефона, по которому можно позвонить, если с вашей JVM будут проблемы.

Исторически (до появления Java 8) между сборками OpenJDK и OracleJDK существовали фактические различия в исходных текстах, и можно было сказать, что OracleJDK был «лучше». Но на сегодняшний день обе версии практически одинаковы, с небольшими отличиями.

Впрочем все сводится к тому, требуется ли вам платная коммерческая поддержка (номер телефона) для используемой версии Java.

Eclipse Temurin от Adoptium (ранее AdoptOpenJDK)

В 2017 году группа членов Java User Group, разработчиков и поставщиков (Amazon, Microsoft, Pivotal, Redhat и другие) основала сообщество под названием AdoptOpenJDK. С августа 2021 года проект AdoptOpenJDK переехал в новый дом и теперь называется проектом Eclipse Adoptium.

Adoptium предоставляет бесплатные, надежные сборки OpenJDK, называемые Eclipse Temurin с более длительной доступностью/обновлениями для различных операционных систем, архитектур и версий.

Настоятельно рекомендую ее, если вы хотите установить Java.

Azul Zulu, Amazon Corretto, SAPMachine

Полный список сборок OpenJDK можно найти на сайте OpenJDK Wikipedia. Среди них Azul Zulu, Amazon Corretto, а также SapMachine и это лишь некоторые из имеющих. Проще говоря, различия сводятся к тому, что у вас есть различные варианты поддержки/ гарантии обслуживания.

Тем не менее, если вы, например, работаете на AWS, имеет смысл просто использовать их сборки Amazon Corretto OpenJDK, если они предлагают версию, которую вы хотите использовать.

Полный обзор дистрибутива OpenJDK

Рафаэль Винтерхальтер (Rafael Winterhalter) составил отличный список всех доступных сборок OpenJDK, включая их описания: ОС, архитектуру, лицензирование, окна поддержки и обслуживания.

Рекомендация

Повторим с еще раз, что в 2022 и 2023 годах, если у вас нет специфических требований, возьмите файл jdk.zip (.tar.gz/.msi/.pkg) с сайта https://adoptium.net (под названием Eclipse Temurin) или выберите пакет, предоставленный вашим поставщиком ОС/облака.

Возможности Java 8–19

Как уже упоминалось в самом начале этого руководства: практически все (не придирайтесь) функции языка Java 8 работают в Java 19. То же самое относится и ко всем другим версиям Java между ними.

Что в свою очередь означает, что знание всех языковых возможностей Java 8 служит очень хорошей базой в изучении Java, а все остальные версии (Java 9–19) в значительной степени дают дополнительные функции поверх этого базового уровня.

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

— Java 8 —

Java 8 была массовым релизом, и вы можете найти список всех функций на веб‑сайте Oracle. Однако здесь я хотел бы упомянуть два основных набора функций:

Возможности языка: лямбды и т.д.

До Java 8 всякий раз, когда вы хотели создать экземпляр, например, нового Runnable, вам приходилось писать анонимный внутренний класс следующим образом:

 Runnable runnable = new Runnable() < @Override public void run()< System.out.println("Hello world !"); >>;

С лямбда-выражениями тот же код выглядит так:

Runnable runnable = () -> System.out.println("Hello world two!");

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

Коллекции и потоки

В Java 8 вы также получили функциональный стиль операций для коллекций, также известный как Stream API. Быстрый пример:

List list = Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");

До появления Java 8, вам приходилось писать циклы for, чтобы что‑то сделать с этим списком.

С помощью API Streams вы можете сделать следующее:

list.stream() .filter(name -> name.startsWith("f")) .map(String::toUpperCase) .sorted() .forEach(System.out::println);

Очевидно, что в рамках данного руководства я могу только дать лишь краткий обзор каждого недавно добавленного метода Stream, Lambda или Optional в Java 8.

— Java 9 —

Java 9 также была довольно большой версией, с несколькими дополнениями:

Коллекции

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

List list = List.of("one", "two", "three"); Set set = Set.of("one", "two", "three"); Map map = Map.of("foo", "one", "bar", "two");
Streams

Потоки получили несколько дополнений в виде методов takeWhile, dropWhile и iterate.

Stream stream = Stream.iterate("", s -> s + "s") .takeWhile(s -> s.length() < 10);
Optionals

Optionals получили метод ifPresentOrElse, которого очень не хватало.

user.ifPresentOrElse(this::displayAccount, this::displayLogin);
Интерфейсы

Интерфейсы получили private методы:

public interface MyInterface < private static void myPrivateMethod()< System.out.println("Yay, I am private!"); >>
Другие возможности языка

И пара других улучшений, таких как улучшенный оператор try‑with‑resources или расширения diamond оператора.

JShell

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

% jshell | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell> int x = 10 x ==> 10
HTTPClient

В Java 9 появилась начальная предварительная версия нового HttpClient. До этого встроенная поддержка Http в Java была довольно низкоуровневой, и вам приходилось прибегать к использованию сторонних библиотек, таких как Apache HttpClient или OkHttp (кстати, отличные библиотеки!).

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

Project Jigsaw: Модули Java и мультирелизные JAR-файлы

В Java 9 появилась система модулей Jigsaw, которая чем‑то напоминает старую добрую спецификацию OSGI. В задачи данного руководства не входит подробное описание Jigsaw — посмотрите предыдущие ссылки, чтобы узнать больше.

Мультирелизные JAR‑файлы позволили создать один файл.jar, который содержит различные классы для различных версий JVM. Таким образом, ваша программа может вести себя по‑разному / использовать разные классы, например, при запуске на Java 8 и Java 10.

- Java 10 -

В Java 10 было внесено несколько изменений, таких как сборка мусора и т. д. Но единственное реальное изменение, которое вы, как разработчик, скорее всего заметите, — это введение ключевого слова «var», также называемого выводом типа локальной переменной.

Вывод типа локальной переменной: ключевое слово var
// Pre-Java 10 String myName = "Marco"; // With Java 10 var myName = "Marco"

Похоже на Javascript, не так ли? Тем не менее, Java все еще строго типизирован и var применяется только к переменным внутри методов (спасибо, dpash, за то, что снова указали на это).

- Java 11 -

Java 11 также была несколько меньшей версией с точки зрения разработчика.

Строки и файлы

Строки и файлы получили несколько новых методов (здесь перечислены не все):

"Marco".isBlank(); "Mar\nco".lines(); "Marco ".strip(); Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!"); String s = Files.readString(path);
Запуск исходных файлов

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

ubuntu@DESKTOP-168M0IF:~$ java MyScript.java
Вывод типа локальной переменной (var) для лямбда-параметров

Заголовок говорит сам за себя:

(var firstName, var lastName) -> firstName + lastName
HttpClient

HttpClient из Java 9 в его окончательной, не предварительной версии.

Прочее

Flight Recorder (Регистратор полетов), сборщик мусора No‑Op, Nashorn‑Javascript‑Engine объявлен deprecated (устаревшим) и т. д.

- Java 12 -

В Java 12 появилось несколько новых функций и исправлений, но единственные, о которых стоит упомянуть здесь, это поддержка Unicode 11 и предварительный просмотр нового выражения switch, о котором вы узнаете в следующем разделе.

- Java 13 -

Полный список возможностей можно найти здесь, но в основном вы получаете поддержку Unicode 12.1, а также две новые или улучшенные превью функции (могут быть изменены в будущем):

Switch выражение (Preview — предварительная версия)

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

Старые операторы switch выглядели следующим образом:

switch(status) < case SUBSCRIBER: // code block break; case FREE_TRIAL: // code block break; default: // code block >

В то время как в Java 13 операторы switch могут выглядеть следующим образом:

boolean result = switch (status) < case SUBSCRIBER ->true; case FREE_TRIAL -> false; default -> throw new IllegalArgumentException("something is murky!"); >;
Многострочные строки (предварительная версия)

Наконец‑то, вы можете сделать это на Java:

String htmlBeforeJava13 + " \n" + " 

Hello, world

\n" + " \n" + "\n"; String htmlWithJava13 = """

Hello, world

""";

- Java 14 -

Switch выражения (стандарт)

Switch выражения, которые были превью функцией в версиях 12 и 13, теперь стандартизированы.

int numLetters = switch (day) < case MONDAY, FRIDAY, SUNDAY ->6; case TUESDAY -> 7; default -> < String s = day.toString(); int result = s.length(); yield result; >>;
Records (Записи - превью)

Теперь существуют классы Records (записей), которые помогают упростить задачу написания большого количества шаблонного кода на Java.

Посмотрите на этот класс до Java 14, который содержит только данные, (потенциально) геттеры/сеттеры, equals / hashcode, toString.

final class Point < public final int x; public final int y; public Point(int x, int y) < this.x = x; this.y = y; >> // реализация equals, hashCode, toString на основе состояния // ничего больше

С записями теперь это может быть записано следующим образом:

record Point(int x, int y)

Опять же, это предварительная версия, которая может быть изменена в будущих выпусках.

Полезные исключения NullPointerExceptions

Наконец, исключения NullPointerExceptions описывают, какая именно переменная имела значение NULL.

author.age = 35; --- Exception in thread "main" java.lang.NullPointerException: Cannot assign field "age" because "author" is null
Сопоставление с образцом для InstanceOf (предварительная версия)

Раньше вам приходилось приводить ваши объекты (выполнять cast) внутри instanceof, как это показано ниже:

if (obj instanceof String) < String s = (String) obj; // использование s >

Теперь вы можете сделать это, фактически отказавшись от приведения.

if (obj instanceof String s)
Инструмент упаковки (инкубатор)

Существует инструмент jpackage (инкубатор), который позволяет упаковать ваше Java‑приложение в пакеты для конкретной платформы, включая все необходимые зависимости.

  • Linux: deb и rpm
  • macOS: pkg и dmg
  • Windows: msi и exe
Сборщики мусора

Сборщик мусора Concurrent Mark Sweep (CMS) был удален, и был добавлен экспериментальный сборщик мусора Z.

- Java 15 -

Текстовые блоки / многострочные строки

Представленные в качестве экспериментальной функции в Java 13 (см. выше), многострочные тексты теперь готовы к использованию.

String text = """ Lorem ipsum dolor sit amet, consectetur adipiscing \ elit, sed do eiusmod tempor incididunt ut labore \ et dolore magna aliqua.\ """;
Запечатанные (sealed) классы - превью

Если вы когда‑либо хотели иметь еще более жесткий контроль над тем, кому разрешено создавать подклассы ваших классов, теперь есть функция sealed .

public abstract sealed class Shape permits Circle, Rectangle, Square

Это означает, что хотя класс является public , единственными классами, которым разрешено создавать подклассы, Shape , являются Circle , Rectangle и Square .

Записи и сопоставление с образцом

Функции Records и Pattern Matching из Java 14 (см. выше) все еще находятся на стадии предварительной версии и еще не доработаны.

Nashorn Javascript Engine

После того, как движок Nashorn Javascript Engine был объявлен устаревшим в Java 11, он был окончательно удален в JDK 15.

ZGC: готов к продакшн

Z Garbage Collector больше не обозначен как экспериментальный. Теперь он готов к использованию в продакшн.

- Java 16 -

Сопоставление шаблонов для instanceof
if (obj instanceof String) < String s = (String) obj; // например, s.substring(1) >

Теперь вы можете сделать следующее:

if (obj instanceof String s) < // Пусть сопоставление шаблонов сделает свою работу! // . s.substring(1) >
Каналы сокетов Unix-домена

Теперь вы можете подключаться к сокетам Unix‑домена (также поддерживаются macOS и Windows (10+).

 socket.connect(UnixDomainSocketAddress.of( "/var/run/postgresql/.s.PGSQL.5432"));
API стороннего компоновщика - превью

Планируемая замена JNI (Java Native Interface), позволяющая выполнять компоновку с нативными библиотеками (например, с библиотеками языка C).

Записи и сопоставление с образцом

Обе функции теперь готовы к продакшн и больше не отмечены in preview .

Запечатанные классы

Запечатанные классы (начиная с Java 15, см. выше) все еще находятся в предварительной версии.

- Java 17 -

Java 17 — это новая версия Java с долгосрочной поддержкой (LTS) после Java 11.

Сопоставление шаблонов для switch (предварительная версия)

Уже доступно на многих других языках:

public String test(Object obj) < return switch(obj) < case Integer i ->"An integer"; case String s -> "A string"; case Cat c -> "A Cat"; default -> "I don't know what it is"; >; >

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

Запечатанные классы (завершена)

Функция, которая была представлена ​​в Java 15 в качестве предварительной версии, теперь завершена.

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

public abstract sealed class Shape permits Circle, Rectangle, Square

Это означает, что хотя класс Shape является публичным, единственными классами, которым разрешено создавать его подклассы являются Circle , Rectangle и Square .

API внешних функций и памяти (инкубатор)

Замена нативного интерфейса Java (JNI). Позволяет вызывать нативные функции и обращаться к памяти за пределами JVM. Пока это вызовы на C, но в будущем планируется поддержка дополнительных языков (таких как C++, Fortran).

Прекращение поддержки диспетчера безопасности

Начиная с Java 1.0, существовал менеджер безопасности. Теперь он устарел и будет удален в одной из будущих версий.

- Java 18 -

UTF-8 по умолчанию

Если вы пытались, например, читать файлы без явного указания окончания символов, то в предыдущих версиях Java использовалась кодировка операционной системы (например, UTF-8 в Linux и macOS и Windows-1252 в Windows). В Java 18 она изменилась на UTF-8 по умолчанию.

Простой веб-сервер

Java 18 теперь поставляется с простейшим HTTP‑сервером, с которого вы можете начать:

jwebserver

Подробнее о его возможностях можно узнать здесь .

Другие не столь захватывающие вещи/инкубационные возможности

Полный список и обзор смотрите в этой статье .

- Java 19 -

В Java 19 добавлено несколько интересных функций, таких как Virtual Threads и новый Foreign Function & Memory API , а также структурированный параллелизм и Vector API , но все они находятся в режиме предварительного просмотра, поэтому могут быть изменены в следующих релизах.

Если вы хотите узнать об этих функциях и о том, что будет дальше, ознакомьтесь с этой статьей .

Заключение

К настоящему моменту у вас должно быть довольно хорошее представление о нескольких вещах:

  • Как установить Java, какую версию получить и где ее получить (подсказка: Adoptium).
  • Что такое дистрибутив Java, какие из них существуют и чем они отличаются.
  • В чем разница между конкретными версиями Java.

Обратная связь, исправления и ваш вклад всегда приветствуются! Просто оставьте комментарий внизу.

Спасибо за прочтение!

Благодарности

Стивену Колеборну, который написал фантастическую статью о различных доступных дистрибутивах Java.

Тренды Java в 2022 году: JDK 18 и 19, Project Loom и Data mesh

Java-университет

Тренды Java в 2022 году: JDK 18 и 19, Project Loom и Data mesh - 1

Ну вот, 2022-й год начался. Пока у большинства еще новогодние каникулы с шампанским и оливье, мы будем говорить о трендах в мире Java. Возможно, это поможет вам проанализировать свою карьеру, выучить новую технологию или придумать план развития на наступивший год. Специалист по языку Java и лектор Андрей Родионов, а также архитектор решений в EPAM и глава программного комитета Devoxx Ukraine Олег Цаль-Цалько рассказали о том, что ждет Java в 2022 году и ближайшем будущем.

Каковы перспективы Java в 2022 году?

Тренды Java в 2022 году: JDK 18 и 19, Project Loom и Data mesh - 2

В этом году ожидаем выхода двух следующих версий JDK 18 (в марте) и JDK 19 (в сентябре). Из потенциально интересного для большинства Java-разработчиков в JDK 18 может быть:

  • Встроенный Simple Web Server, без поддержки сервлет-контейнера, который можно будет использовать для быстрого прототипирования и тестирования, по аналогии с аналогичными мини веб-серверами в Python, Ruby, PHP.
  • Продолжающий совершенствоваться pattern matching.

Что касается JDK 19, уже есть Early-Access Build, но еще нет официального списка, что же в него планируется включить. Хочется верить, что в JDK 19, по крайней мере, войдет первый стабильный прототип Project Loom, для которого недавно появились проекты спецификаций и чья последняя сборка базируется на JDK 19. О Project Loom мы еще поговорим детальнее ниже.

Для каких сфер Java остается безальтернативным решением, где она предпочтительна?

Андрей Родионов:

Тренды Java в 2022 году: JDK 18 и 19, Project Loom и Data mesh - 3

К счастью, нельзя говорить о безальтернативности Java для какой-либо из сфер, но можно говорить о Java как о некой золотой середине для разработки enterprise приложений, бэкенда и микросервисов. Стоит также отметить увеличивающееся количество разных дистрибутивов JDK от разных вендоров (кроме Oracle): Amazon, Microsoft, Alibaba, Red Hat, Bellsoft (основанная выходцами из Центра Разработок Oracle в Санкт-Петербурге) и другие. Полный набор дистрибутивов доступен по ссылке. Альтернативы всегда есть, но наибольшее применение Java находит на backend в enterprise разработке. Большинство больших компаний выбирают Java для своих больших и сложных систем. Причины все те же: количество разработчиков и экспертизы на рынке, огромная экосистема и мощная JVM платформа.

Какие перспективы у других jvm языков, в частности, у Kotlin, по сравнению c Java?

Андрей Родионов:

Чтобы понять какие из JVM-языков популярны, достаточно открыть документацию по Spring, Micronaut, Vert.x и посмотреть, на каких языках приводятся примеры кода – общими будет Java и Kotlin. Нельзя сказать, что наблюдается массовый переход проектов на Kotlin, но его популярность для бэкенда продолжает расти и множество фреймворков старается его включить в свою экосистему. Что касается Scala, то выходят и ее новые версии, и она дальше активно используется для ML, data processing и там, где более удобной является функциональная парадигма программирования.

Олег Цаль-Цалько:
  • Они не настолько круче, чтобы все прямо взяли и перешли на них.
  • Они используются в том же сегменте, что и Java.
  • Java понемногу берет все лучшее от других языков и становится лучше.

Будет ли падение качества Java в связи с более короткими межрелизными интервалами?

Олег Цаль-Цалько:

Думаю, что нет. По крайней мере, сейчас я могу выделить больше позитива от частых релизов. Мы видим, что новые клевые фичи появляются намного чаще. Теперь не надо ждать 5 лет, чтобы в языке появилось что-то новое. Само собой теперь не стоит ожидать таких грандиозных релизов, как Java 8, потому что фичи теперь появляются маленькими итерациями.

Есть ли фичи в новых версиях Java, которые особенно важны для разработчиков?

Олег Цаль-Цалько:

В последних версиях Java появилось несколько интересных фич, таких как Pattern Matching, Sealed Classes и Records. Я бы рекомендовал посмотреть на их возможности. Конечно, наиболее серьезные и ожидаемые фичи планируются в рамках Project Loom и Project Valhalla, но я думаю, что фичи в рамках этих проектов тоже будут релизиться постепенно.

Фреймворк Spring: будет ли он и дальше множить свою экосистему под разнообразные потребности?

Андрей Родионов:

Что касается Spring Framework, то его разработка была сосредоточена на поддержке разных возможностей Spring Cloud и возможности компиляции Spring Boot в нативные бинарные файлы – проект Spring Native, который планируется в будущем сделать частью Spring Core. В этом плане Spring отставал от Micronaut и Quarkus из-за активного использования reflection и динамической кодогенерации. Что касается Spring Framework 6, советую посмотреть доклад Spring 6 and Beyond Что нового в Spring Framework 6? с конференции Joker (от Олега Докуки и Алексея Нестерова). Из ключевого – переход на JDK 17, отказ от XML Configuration и Autowire через сеттеры, дальнейшее развитие поддержки Kotlin и проекта Spring Fu.

Олег Цаль-Цалько:

Spring как самый популярный Java FW в наше время не хочет отдавать пальму первенства. Я уверен, что команда разработчиков будет прилагать все усилия к развитию Spring. Spring заполняет все новые и новые ниши. Например, Spring сделал очень много в области Reactive Streams / Reactive Programming со своим Project Reactor. Теперь они продвигают RSoket protocol, что тоже выглядит многообещающе.

Расскажите о проекте Loom: для чего нужен, какие проблемы решает?

Андрей Родионов:

Project Loom – это, наверное, самое интересное новшество, которое может стать новым тектоническим сдвигом всей JVM-платформы и всех языков поверх JVM. Project Loom может не затронет так сильно обычных разработчиков, но точно повлияет на всю экосистему, библиотеки, фреймворки, другие JVM-языки использующие многопоточность. Project Loom вводит новую абстракцию потоков – virtual threads (аналог корутин). Если раньше Java thread был непосредственно привязан к потоку операционной системы (ОС), и создание нового потока в Java приводило к созданию нового потока ОС, то с virtual threads эта связь один-к-одному разрывается. При создании нового виртуального потока не будет создаваться новый потока ОС, а для выполнения непосредственных вычислений будет переиспользоваться один из так называемых carrier thread (некий аналог пула потоков ОС). Таким образом, поверх одного потока ОС может работать несколько виртуальных потоков. Для вычислительных задач такая модель виртуальных потоков не дает никаких преимуществ, и скорее замедляет скорость вычислений, но для блокирующих операций, типа обработки HTTP-запросов, ожидания ответов от БД или от микросервисов данная модель будет существенным плюсом. Дело в том, что при теперешней модели потоков блокировка/ожидание Java thread приводила к простою потока ОС, – это было тратой ресурсов и требовало создавать больше потоков ОС. В модели с виртуальными потоками, блокировка/ожидание виртуального потока приведет к тому, что будет освобождаться carrier thread, поверх которого работал виртуальный поток, и на нем будет запускаться другой виртуальный поток. Таким образом, потоки ОС будут использоваться более оптимально, и потребуется их меньшее количество для выполнения аналогичных задач. Соответственно, производители библиотек, фреймворков и JVM-языков должны будут адаптировать код под виртуальные потоки. Поэтому для них грядет большое переписывание 🙂 Кроме модели виртуальных потоков, также планируется привнести и новый API для упрощения оркестрации потоков – так называемый structured concurrency. Сейчас, к примеру, structured concurrency активно используется в Kotlin-корутинах и Scala ZIO. К сожалению, версия JDK и даже год выхода Project Loom пока неизвестны. На вопрос о дате выхода главный архитектор Java-платформы Брайан Гетц отвечает философской фразой: ”It will be ready, when it will be ready”. Поэтому ждем и можем пробовать экспериментальные сборки Project Loom.

Олег Цаль-Цалько:

Loom – это большой umbrella project, в рамках которого команда OpenJDK и Oracle работает над Concurrency нововведениями в Java и JVM: virtual threads, fibers и continuations. Скорее всего, релиз этих фичей будет постепенный. На данный момент есть только Early Access builds для Virtual threads supports. Если говорить конкретно о virtual threads, его основная цель – упрощение многопоточной модели разработки в Java с помощью использования миллиона легковесных потоков с той же семантикой, как и у обычных платформенных потоков. Под капотом эти потоки будут менеджиться внутри ForkJoinPool и переиспользовать платформенные потоки.

Какие прогнозы развития Java в мире глобальных трендов – микросервисов, облачной архитектуры, блокчейна, ИИ?

Андрей Родионов:

Если говорить, о глобальных трендах, то они не особо изменились. По-прежнему основным трендом продолжает оставаться Kubernetes и инфраструктура вокруг него в виде Service mesh. Набирает также популярность Data mesh, как некая абстракция для управления распределенными источниками и хранилищами данных.

JDK 19 начинает обретать очертания

JDK 19 начинает обретать очертания

Перенос на платформу Linux/RISC-V становится официальной целью Java 19 – стандартной версии Java без долгосрочной поддержки, которая должна появиться в сентябре.

Официально объявлено, что пакет Java Development Kit 19, появление которого ожидается в сентябре текущего года, обеспечит перенос JDK в среду Linux с открытым кодом на процессорах с набором инструкций RISC-V.

В соответствии с текущими планами по улучшению Java пакет JDK 19 (или просто Java 19) будет поддерживать широкий набор функций, начиная от универсальных дженериков и заканчивая объектами значений. Пока же единственным официально подтвержденным новшеством является перенос на платформу RISC-V. Версия JDK 19 будет выпущена вслед за JDK 18, которая появилась 22 марта. Выпуск релизов стандартной версии Java происходит раз в полгода.

После переноса на платформу Linux/RISC-V технология Java сможет работать с набором аппаратных инструкций, который уже поддерживается широким спектром языковых средств компиляции. На практике RISC-V представляет собой семейство связанных наборов команд. Пока перенос на платформу Linux/RISC-V будет поддерживать только конфигурацию RV64GV – 64-разрядную архитектуру набора команд общего назначения, включающего векторные инструкции. В будущем разработчики Java могут рассмотреть и другие конфигурации RISC-V.

Предполагается поддержка следующих компонентов виртуальной машины HotSpot: интерпретатор шаблонов, JIT-компилятор C1 (клиентский), JIT-компилятор C2 (серверный) и все существующие сборщики мусора, включая ZGC и Shenandoah. Фактический перенос почти завершен; основное внимание в JDK Enhancement Proposal (JEP) уделяется интеграции переноса в основной репозитарий JDK.

Помимо переноса на платформу RISC-V, похоже, можно говорить о том, что предварительная версия интерфейса API внешних функций и памяти, позволяющего программам Java взаимодействовать с кодом и данными за пределами исполняемой среды виртуальной машины Java, также ориентирована на JDK 19, поскольку API ссылается на JDK 19. Но по состоянию на 14 марта API внешних функций и памяти на странице JDK 19 OpenJDK не присутствует.

Как JDK 18, так и JDK 19 не предполагают долгосрочной поддержки. Их сопровождение ограничено всего лишь шестью месяцами. Текущая же версия, JDK 17, относится как раз к числу выпусков с долгосрочной поддержкой, осуществляемой на протяжении нескольких лет.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *