Нововведения Java 17
Java 17 — LTS-релиз. Для перехода с Java 11 важны не только возможности, финализированные именно в 17, но и изменения языка, появившиеся в релизах 12–16 и уже ставшие стабильной частью платформы.
Sealed classes — финальная возможность Java 17
Sealed-тип ограничивает список прямых наследников:
sealed interface Result permits Success, Failure {}
record Success(String value) implements Result {}
record Failure(String message) implements Result {}Разрешённый наследник должен быть final, sealed или non-sealed.
Если типы находятся в unnamed module, они должны быть в одном package;
в named module достаточно одного модуля.
Что уже доступно при переходе с 11
Records
record Point(int x, int y) {
Point {
if (x < 0 || y < 0) throw new IllegalArgumentException();
}
}Record — компактный класс для прозрачного носителя данных. Он получает
accessors, constructor, equals, hashCode, toString, является final,
но может реализовывать интерфейсы. Records стали финальной возможностью в 16,
а не в 17.
Pattern matching for instanceof
if (value instanceof String text && !text.isBlank()) {
use(text);
}Отдельное приведение не нужно; область видимости pattern variable зависит от потока управления. Возможность финализирована в Java 16.
Switch expressions
int weight = switch (priority) {
case LOW -> 1;
case NORMAL -> 5;
case HIGH -> 10;
};Несколько инструкций оформляются блоком с yield. Это финальная возможность
Java 14. Pattern matching для switch в Java 17 был только preview и требовал
флагов; стабильный вариант более поздних Java отличается, поэтому такой код
нельзя считать обычной возможностью Java 17.
Text blocks
String json = """
{
"status": "ok"
}
""";Text blocks финализированы в Java 15. Отступ определяется общей левой границей, а перевод строки перед закрывающими кавычками влияет на результат.
Изменения платформы
- усилена инкапсуляция внутренних API JDK: нелегальный reflection может сломаться;
- восстановлена строгая семантика floating point без необходимости
strictfp; - добавлены новые интерфейсы генераторов псевдослучайных чисел;
- RMI Activation удалён;
- появились контекстные фильтры десериализации;
- Vector API и Foreign Function & Memory API в 17 ещё были incubator.
Перед миграцией проверяют toolchain, плагины сборки, библиотеки, JVM-флаги, reflection и удалённые модули. Компиляция и тесты важнее простого изменения номера образа.
Связанные темы: Интерфейсы Java, Equals и hashCode, Структура JDK.
Вопросы для собеседования
- Главная финальная языковая возможность 17? Sealed classes/interfaces.
- Records появились именно в 17? Нет, финализированы в 16, но доступны в 17.
- Можно ли record наследовать от своего класса? Нет, он неявно final и
наследует
Record; интерфейсы реализовывать можно. - Что обязан указать наследник sealed-типа?
final,sealedилиnon-sealed. - Был ли pattern switch стабильным в 17? Нет, только preview.
- Почему миграция может сломать reflection? Внутренние JDK packages сильнее инкапсулированы.
- Что проверить кроме исходников? Сборку, зависимости, JVM flags, контейнерный образ и интеграционные тесты.