Какие ключевые изменения в работе с модулями (JPMS) произошли между Java 11 и Java 18?

«Какие ключевые изменения в работе с модулями (JPMS) произошли между Java 11 и Java 18?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основные изменения касаются Java Platform Module System (JPMS), представленной в Java 9, и её последующего развития. Между 11 и 18 LTS-версиями были введены важные улучшения для удобства использования:

  • JEP 403: Strongly Encapsulate JDK Internals (Java 16, закреплено в 17) — Внутренние API JDK (например, sun.misc.Unsafe) по умолчанию стали строго инкапсулированы. Это повышает безопасность и стабильность. Для доступа требуется явное разрешение через --add-opens.
  • JEP 396: Strongly Encapsulate JDK Internals by Default (Java 16) — Предварительный шаг к JEP 403, установивший строгую инкапсуляцию по умолчанию.
  • Упрощение миграции. Появились флаги для облегчения перехода с классического classpath на modulepath, помогающие обрабатывать автоматические модули и доступ к внутренним API.
  • Улучшения в jlink и jpackage (Java 14+). Инструменты для создания собственных образов среды выполнения (JRE) и нативных пакетов приложений стали стабильнее и функциональнее, что напрямую связано с модульностью.

Почему это важно? Эти изменения окончательно закрепили модульность как основу платформы, повысили безопасность и упростили создание минимальных деплоябельных образов Java-приложений.