Что такое флаг --release в компиляторе Java 9?

Java 9 javac имеет новый флаг --release:

> javac --help
...

--release <release>
    Compile for a specific VM version. Supported targets: 6, 7, 8, 9

Чем он отличается от -source а также -target флаги? Это просто ярлык для -source X -target X?

2 ответа

Решение

Не совсем.

JEP 247: Компиляция для более старых версий платформы определяет этот новый параметр командной строки, --release:

Мы определили новую опцию командной строки, --release, который автоматически настраивает компилятор для создания файлов классов, которые будут связаны с реализацией данной версии платформы. Для платформ, определенных в javac, --release Nэквивалентно-source N -target N -bootclasspath <bootclasspath-from-N>, (акцент мой)

Так что нет, это не эквивалентно -source N -target N, Причина этого дополнения указана в разделе "Мотивация":

javac предоставляет две опции командной строки, -source а также -target, который может использоваться для выбора версии языка Java, принятой компилятором, и версии файлов классов, которые он создает, соответственно. Однако по умолчанию javac компилируется с самой последней версией API платформы. Поэтому скомпилированная программа может случайно использовать API-интерфейсы, доступные только в текущей версии платформы. Такие программы не могут работать на более старых версиях платформы, независимо от значений, переданных -source и `-целевой. опции. Это долговременная проблема удобства использования, так как пользователи ожидают, что с помощью этих опций они получат файлы классов, которые могут работать на указанной версии платформы.

Короче говоря, указание параметров источника и цели недостаточно для кросс-компиляции. Так как javacпо умолчанию компилируется с использованием самых последних API-интерфейсов платформы, они не могут гарантированно работать на более старых версиях. Вам также необходимо указать -bootclasspath опция, соответствующая более старой версии для правильной кросс-компиляции. Это будет включать в себя правильную версию API для компиляции и разрешить выполнение в более старой версии. Поскольку об этом часто забывают, было решено добавить один параметр командной строки, который делал все необходимые вещи для правильной кросс-компиляции.

Дальнейшее чтение в списке рассылки и Oracle Docs. Оригинальная ошибка была подана здесь. Обратите внимание, что после интеграции этой опции сборки JDK поставляются в комплекте с описаниями API-интерфейсов платформы более ранних выпусков, упомянутых в разделе "Риски и предположения". Это означает, что для работы кросс-компиляции вам не нужна старая версия, установленная на вашем компьютере.

--release X это больше, чем просто ярлык -source X -target X так как -source а также -target недостаточно для безопасной компиляции в более старую версию. Вам также нужно установить -bootclasspath флаг, который должен соответствовать старому выпуску (и этот флаг часто забывают). Итак, в Java 9 они сделали один --release флаг, который заменяет три флага: -source, -target а также -bootclasspath,

Итак, это пример компиляции в Java 1.7:

javac --release 7 <source files>

Обратите внимание, что вам даже не нужно устанавливать JDK 7 на ваш компьютер. JDK 9 уже содержит необходимую информацию, чтобы предотвратить случайную ссылку на символы, которых не было в JDK 7.

Другие вопросы по тегам