Огляд Java 17: переваги та недоліки
Микита Земницький, Java Developer
Java 17 дебютувала відносно давно, але фактично не використовується девелоперами. За даними NewRelic, на початку 2022 року доля цієї версії склала 0,37% проти 48,5% у 11-ї та 46,5% у 8-ї! На мою думку, розробникам треба більше дізнатися про переваги мови програмування Java 17. Саме цьому й присвячена стаття. Я розкажу про основні нововведення у мові, безпеці, платформі, збирачах сміття. Втім, опишу я не тільки переваги Java цієї версії, але й деякі недоліки…
Чим особлива нова Java 17?
Java 17 — це реліз формату Long-Term Support із підтримкою до 2029 року. Минулою LTS-версією була Java 11, відома з 2018 року. Ви можете й надалі користуватися нею, адже знайдені вразливості у безпеці будуть гарантовано виправлятися до вересня 2026 року. І хоча у одинадцятої Java переваги не обмежуються цим, прогрес не зупинити. Саме тому я раджу нову довготривалу версію.
У більшості проєктів використовуються LTS-релізи. Проте кожні півроку виходять нові версії формату non-LTS. Це, наприклад, від 12-ї до 16-ї версії включно, а також Java 18 і 19. Проте підтримка таких варіантів завершується із дебютом нового виконання. Через це розробнику треба постійно мігрувати між версіями. Але тоді можуть виникати проблеми із залежностями, які не готові до нової версії. Саме так розвивається мова програмування Java, переваги LTS-релізів в такому разі очевидні. Тож важливо знати більше про актуальну довготривалу версію.
Ключові новинки Java 17
Той, кому близька мова програмування Java, переваги серед нововведень 17 версії точно знає. Тому я коротко пробіжусь по основним. Наприклад, були додані Sealed-класи, розширені екземпляри (це Enhanced instanceof), Switch-вирази, а також текстові блоки й рекорди (або Records).
У цьому LTS-релізі Java переваги та недоліки інколи йдуть поруч. Наприклад, з’явився Vector API. Але він є тільки в інкубаторі, і модуль підключається окремою командою. Ще додано Memory API і Foreign Function, а Security Manager помічений Deprecate. Плюс пригадаємо зміни в MacOS, в якій тепер є рендеринг із використанням Metal API. До того ж, з’явилися давно очікувані Null Pointer Exception, які показують багато інформації щодо помилок. І не просто рядок, де зафіксована помилка, а конкретний об’єкт із Null.
І трохи змін у частині безпеки. Сучасна криптографія та контекстно-залежні фільтри десеріалізації були модернізовані. А псевдовипадкове число розширили, тобто воно тепер ще більш псевдовипадкове. Це безсумнівні переваги мови програмування Java 17, які важливі кожному розробнику.
Головні нововведення JDK
- Видалено Finalize з деяких методів
Раніше після «загибелі» об’єкту він ставав у чергу, аби Finalize реалізував своє призначення. Але його виконання за специфікацією навіть до завершення роботи вже JVM не було гарантованим. В результаті від цього функціоналу в JDK поступово відмовляються.
- Зміни інтерфейсів Packer та Unpacker, реалізації класу Pack200
Раніше клас Pack200 використовувався здебільшого для внутрішніх потреб. Тому не так багато розробників буде розчароване подібним рішенням. А конструктор класу URLDecoder у цьому релізі повністю видалений.
- Чимало класів AWT та Swing змінили видимість
Велика частина з них були публічними, тобто були доступними звідусіль. Але в цій версій багато класів приховано. Втім, це не стосується основних інтерфейсів, що можна занести до переваг мови програмування Java 17.
- Позначення API Applet для видалення
Ви можете ним користуватися, але це вже не рекомендовано з огляду перспектив.
Основні зміни JVM
- Garbage-колектори
CMS видалено, через що потрібно обирати збирач сміття. За замовчуванням це G1. Також існує ZGC, який представлено ще в 11-й версії як експериментальний. Проте це навряд чи можна згадувати як переваги Java того релізу, адже є досі невиправлені мінуси (тому цей колектор краще не брати). Що стосується G1, то у ньому з’явився Abortable Mixed Collection. Частина регіонів під час збору сміття буде збиратися без додаткових умов. Це дозволяє повністю зібрати їх за цикл. А інша частина регіонів можуть бути зібрана наступного циклу, якщо першому не вистачить обмеження часу. А ще G1 тепер вміє аллокувати пам’ять та бути NUMA-Aware. Тобто для багатонодних архітектур буде під нові об’єкти виокремлюватися власне місце в пам’яті, яке розташовано у виконавцю ближче до Thread.
- Зменшення пауз
Затримки, які викликає робота Garbage Collector, напружують користувачів. Заради цього у роботі JVM є деякі зміни. Завдяки ним більше процесів можуть тривати одночасно із виконанням застосунку. Це можна однозначно вказати у Java-17 як перевагу.
- Компілятор Just-in-Time
Тепер GraalVM знаходиться в окремому проєкті. Ключовим нововведенням Java Flight Recorder є можливість стрімингу подій. Вони будуть записані у JFR. Це дозволяє бачити зміни в форматі real time.
Порівнюємо G1 та ParallelGC
На мою думку, говорячи про переваги 17-ї Java, варто окремо згадати Garbage Collectors. Найкраще це зробити у порівнянні двох популярних збирачів сміття: G1 і ParallelGC.
G1 — це скорочена назва Garbage-First collector. Він є алгоритмом складання сміття, який представлений у віртуальній машині Oracle HotSpot Java (JVM) 6. Його підтримка починалась із 7 Update 4. Цей збирач виступає довгостроковою заміною CMS та створений для багатопроцесорних комп’ютерів із великим обсягом пам’яті. G1 має досягати потрібних цілей з високою ймовірністю за часом припинення збору сміття. При цьому він повинен показувати високу пропускну здатність на фоні незначних потреб в налаштуваннях.
Зі свого боку ParallelGC інколи подається як збирач пропускної спроможності. Під час роботи він ставить на паузу потоки та виконує в декілька потоків свою задачу. Завдяки цьому мета досягається без перерв, максимально продуктивно. В більшості випадків це ефективний спосіб зменшити час, потрібний для роботи збирача (у порівнянні із програмою). Хоча інколи паузи застосунку через роботу GC можуть бути й довгими.
Недоліки Java 17
- Немає 100% зворотної сумісності
Сумісність є ключовим принципом побудови усіх релізів Java. Проте в новій версії пропала чимала кількість методів, які раніше мали відмітку Deprecated. Девелопери мали час для їх видалення, але якщо ж ви цього досі не зробили, то ваш проєкт може не скомпілюватися.
- Зміни видимості частини внутрішніх модулів
Через це ви позбавлені доступу до таких елементів. Звичайно, тут допоможе поява публічного API, з яким буде потрібний доступ. Але через це потрібно змінювати код. Плюс у цьому релізі відсутня підтримка Spring. Інструмент працюватиме, але без офіційних гарантій.
- Втрати часу
У великих проєктах при міграції на новий реліз ви напевно побачите багато нехай і дрібних, але все ж таки проблем. Хоча підкреслю: це не порівняти з переходом із Java 8 на Java 11. Напевно, ви краще за мене пам’ятаєте, яким болючим був той процес з конфліктами між дуже багатьма залежностями. Особисто мені тоді запам’яталась бібліотека djkloyn, яка на Java 11 виявилась несумісною із Worker Thread. Тоді я вимушений був в принципі відмовитися від такої бібліотеки.
Утім, я впевнений: переваг у мови програмування Java 17 все одно більше. Для мене ця версія цікавіша за всіма пунктами: швидкість, нові функції, мовні застосунки, зокрема, Sealed-класи та Records. Тому раджу спробувати її всім!