Реліз Java 19: 7 нових JEP та ще багато покращень
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Цей день настав! Офіційний реліз JDK 19 вже сьогодні, вже зараз. А це значить, що треба розібратися, що ж в ньому нового.
Java 19 General-Availability
Реліз JDK 19 є десятим за рахунком Feature Release, який було своєчасно випущено в рамках шестимісячної каденції. Такий рівень передбачуваності дозволяє розробникам досягати відносно простого, послідовного та не витратного за часом впровадження інновацій завдяки постійному потоку очікуваних змін.
Ще однією важливою зміною під час релізу Oracle JDK 17 стало введення нових і простіших ліцензійних умов, які дозволять компаніям використовувати Oracle JDK 17, включаючи щоквартальні патчі продуктивності, стабільності та безпеки, безкоштовно протягом щонайменше наступних трьох років, дозволяючи один повний рік перекриття з наступним LTS випуском.
Передплатники Java SE отримують доступ до підтримки Java SE від Oracle та комерційних функцій, таких як GraalVM Enterprise, Java Management Service і Advanced Management Console. Детальніше про нові ліцензійні умови Java SE доступно тут.
Вклад компаній у Java 19
З 19 297 тікетів у JIRA, позначених як виправлені у релізах Java
У Java 19 з 1 962 тікетів у JIRA, позначених як виправлені, 1 383 були завершені Oracle, а 579 були внесені іншими членами спільноти Java.
Що нового у Java 19
JDK Enhancement Papers
Отже, почнемо із глобальних змін, які несуть нові JDK Enhancement Papers (JEP):
- JEP 405 Record Patterns (Preview)
- JEP 422 Linux/RISC-V Port
- JEP 424 Foreign Function & Memory API (Preview)
- JEP 425 Virtual Threads (Preview)
- JEP 426 Vector API (Fourth Incubator)
- JEP 427 Pattern Matching for switch (Third Preview)
- JEP 428 Structured Concurrency (Incubator)
Нововведення у JDK 19 (по за контекстом JEP):
- Можливість керування кодуванням STDOUT/STDERR (JDK-8283620)
- підтримка Unicode 14.0 (JDK-8268081)
- Реалізація Pointer Authentication Code для AARCH64 (Linux only, JDK-8277204)
- Автоматична генерація Class-Data-Sharing (CDS) архіву (JDK-8261455)
Повний перелік нововведень доступний у Release Notes. Найцікавіше (нові JEP) ми все ж таки розглянемо.
Project Loom
JEP 425: Virtual Threads
З’явився новий тип Java-потоків — Virtual Thread. На відміну від класичних потоків, віртуальні вже не мають прямого співвідношення до системних потоків. А також їхня кількість більше не залежить від кількості доступних системних потоків, а лише від наявної пам’яті, якою оперує JVM. Новий функціонал буде доступний у форматі preview feature. Конструкції, з якими доведеться мати справу:
Thread.startVirtual( () -> System.out.println(Thread.currentThread()) );
та
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { executor.submit(() -> { Thread.sleep(Duration.ofSeconds(1)); }); }
Деталізований розбір доступний тут.
JEP 428: Structured Concurrency
Structured Concurrency вже на стадії інкубатора, новий функціонал спрощує багатопотокове програмування за допомогою структурованого паралелізму. Цей паралелізм розглядає декілька завдань, що виконуються в різних потоках, як єдину робочу одиницю, щоб спростити обробку та скасування помилок:
static Callable<Integer> task = () -> {
System.out.println(Thread.currentThread());
Thread.sleep(Duration.ofSeconds(1));
return 42;
};
static void simpleScope() throws InterruptedException {
try(var scope = new StructuredTaskScope<>()) {
var fut = scope.fork(task);
scope.join();
System.out.println(fut.resultNow());
}
}
Деталізований розбір доступний тут, тут, тут і тут.
Project Amber
JEP 405: Record pattern matching
Загалом, patter matching використовується для двох задач: встановлення типу, та приведення змінної до певного типу, якщо змінна такою є, наприклад:
Object object = ...; // any object
if (object instanceof String s) {
int length = s.length();
System.out.println("This object is a string of length" + length);
} else {
System.out.println("This object is not a string.");
}
Що ж стосується рекордів, то тут ситуація може бути наступною:
record Point(int x, int y) {}
var p = (Object) new Point(1, 2);
if (pObject instanceof Point newP) {
System.out.println(newP);
}
Тобто, працює той самий механізм як і раніше, але тепер є можливість організувати більш гранулярний доступ до атрибутів рекорду:
record Point(int x, int y) {}
var p = (Object) new Point(1, 2);
if (pObject instanceof Point(int x, int y)) {
System.out.printf(“Point[x=%d, y=%d]\n”, x, y);
}
Повний та детальний опис функціонала доступний у JEP 405.
JEP 427: Patter matching for switch
У Java 16, JEP 394 розширив оператор instanceof
для використання у межах pattern matching. Це скромне розширення дозволяє спростити знайому ідіому instanceof
та cast
:
if (o instanceof String s) { ... }
Ми часто бажаємо порівнювати змінну з декількома альтернативами. Java підтримує багатосторонні порівняння з допомогою операторів switch
і, починаючи з Java 14, switch expression (JEP 361). Отже, набір гілок if-esle можна переробити на наступну структуру:
static void testFooBar(String s) { switch (s) { case null -> System.out.println("Oops"); case "Foo", "Bar" -> System.out.println("Great"); default -> System.out.println("Ok"); } }
Частіше за все є необхідність визначитися із типом змінної та ії контетом одночасно, тому доводиться робити наступні конструкції:
class Shape {} class Rectangle extends Shape {} class Triangle extends Shape { int calculateArea() { ... } } static void testTriangle(Shape s) { switch (s) { case null: break; case Triangle t: if (t.calculateArea() > 100) { System.out.println("Large triangle"); break; } default: System.out.println("A shape, possibly a small triangle"); } }
Проблема тут полягає в тому, що використання одного шаблону для розрізнення кейсів не виходить за рамки однієї умови — нам потрібен якийсь спосіб виразити уточнення шаблону. Один з підходів полягає у введенні guarded patterns, які дозволяють уточнити шаблон за допомогою довільного булевого визару:
static void testTriangle(Shape s) { 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"); } }
Отже, конструкція case ... when ... -> ...
дозволяє формувати більш складні кейси із використанням patter matching.
Більше матеріалів по Project Amber можна знайти тут і тут.
Project Panama
JEP 424: Foreign Function & Memory API
Нарешті, повноцінна заміна JNI, яка реалізує Application Binary Interface і дозволяє використовувати C ABI, для роботи з нативними С бібліотеками напряму та через extern C з С++ бібліотеками. Якщо хочете розібратися у цій темі, я дуже рекомендую прочитати мій цикл статей тут на DOU:
- Вступи до Project Panama (Частина 1)
- Реалізація варіативних функцій (Частина 2)
- Кодогенерація JEXTRACT (Частина 3)
- Керувати off-heap пам’яттю (Частина 4)
Зверніть увагу, що функціонал доступний у форматі preview feature. Щоб працювати з цим API, треба:
- Скомпілюйте програму за допомогою
javac --release 19 --enable-preview Main.java
та запустіть її за допомогоюjava --enable-preview Main
. - Використовуючи програму запуску вихідного коду, запустіть програму з
java --source 19 --enable-preview Main.java
. - Використовуючи
jshell
, почніть його зjshell --enable-preview
. - Додайте відповідний модуль
--add-modules jdk.incubator.vector --enable-native-access=ALL-UNNAMED
JEP 426: Vectors API
Функціонал, який поставляється у рамках OpenJDK Project Panama не обмежений лише набором класів для експлуатації C ABI у рамках JVM та новим інструментом кодогенерації — jextract. Дуже важливими нововведеннями для розробників є так звані Vectors API — набір класів, суть котрих полягає в наданні певних можливостей для реалізації векторної алгебри (криптографія, мультимедіа, AI/ML). Отже, ця стаття спрямована на те, щоб на певних прикладах показати, що таке Vectors API, звідки воно походить, та як їх використовувати у Java додатках.
Удосконалення API, запропоновані для JDK 19, включають поліпшення завантаження та зберігання векторів з MemorySegments, як визначено в попередньому перегляді Foreign Function and Memory API. JDK 19 також додасть дві перехресні векторні операції, стиснення та розширення, разом з додатковою операцією стиснення векторних масок. Операція стиснення корисна для фільтрації результатів обробки векторів.
Це вже
- Vectors API;
- Streams;
- цикл
for
;
RISC-V
Метою проєкту є створення повнофункціонального переносу OpenJDK на платформу Linux/RISC-V, який може бути інтегрований в основну гілку розробки OpenJDK. Наразі планується підтримка порту JDK 19 на Linux на RISC-V. Вже є успішні спроби повноцінно портувати JDK та JVM на RISC-V, цей порт успішно пройшов тести JTREG, що вже означає, що більшість Java застосунків будуть працювати на цій архітектурі без проблем.
Сам проєкт створення порту JVM містить підлаштування C1, C2 JIT-компіляторів, найкращих GC типу ZGC.
Для довідки: RISC-V — це архітектура набору інструкцій з відкритим кодом та безоплатною ліцензією для обчислювальних платформ, починаючи від вбудованих систем, і закінчуючи корпоративними серверами. Наразі певні клаудпровайдери, типу Alibaba, вже пропонуються RISC-V для всіх бажаючих. Проєкт RISC-V просувають такі мастадонти як Google, nVIDIA, Samsung.
Дистрибутив JDK 19
Офіційні джерела
Офіційний реліз Oracle OpenJDK доступний тут — jdk.java.net/19
Офіційний реліз OracleJDK доступний тут — www.oracle.com/...a/technologies/downloads
Офіційні Java action для GitHub
Реліз вже доступний для GitHub Actions:
steps:
- name: 'Set up latest Oracle OpenJDK 19'
uses: oracle-actions/setup-java@v1
with:
website: jdk.java.net
release: 19
та
steps:
- name: 'Set up latest Oracle JDK 19'
uses: oracle-actions/setup-java@v1
with:
website: java.net
release: 19
Офіційна документація
Ліцензування
Трохи висновків
Java продовжує залишатися мовою програмування № 1 для сучасних технологічних тенденцій. Як показує своєчасне впровадження вдосконалень у Java 19, завдяки постійному ретельному плануванню та залученню екосистеми, платформа Java є добре позиціонованою для сучасного розвитку і зростання в хмарі.
Новий реліз хоч і не є Long-Time-Support версією, але несе дуже важливі зміни у JDK, особливо у два напрями:
- багато-потоковість
- авто-векторізація
Отже, цей реліз, та наступні будуть цікаві усім, хто розробляє мережеві додатки, проекти з досить складною математикою типу Tribuo, або інші AI/ML фрейморки, а також ті розробники хто захоче створити ті бібліотеки, яких ще не існує у Java екосистемі.
Слідкуйте за новинами та оновленнями за посиланням:
- Dev.java (Спеціальний портал Oracle для поглиблення ваших знань з Java та участі у комʼюніті).
- Inside.java (суто-технічний блог який ведуть архітектори та інженери що розроблюють Java).
- Inside.java подксат про JDK, JVM, GC, core libs і так далі.
- Inside.java Newscasts (щотижневе YouTube-шоу, суто про Java).
- Java on YouTube (все про Java та екосистему).
- OpenJDK mailing lists (місце, де можна дізнатися поточний стан речей у OpenJDK комʼюніті).
- Підписуйтесь на OpenJDK and Java on Twitter.
----
Ну, і підписуйтесь на мене у Twitter. Там я роблю щотижневий #JavaTuesdayThread — про поглиблений функціонал JDK, про C/C++ у контексті Java та ще багато чого іншного.
23 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів