web-dev-qa-db-fra.com

Qu'est-ce que l'indicateur --release dans le compilateur Java 9?

javac de Java 9 a un nouveau drapeau --release:

> javac --help
...

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

En quoi est-ce différent de -source et -target drapeaux? Est-ce juste un raccourci pour -source X -target X?

59
ZhekaKozlov

Pas exactement.

JEP 247: Compiler pour les anciennes versions de plate-forme définit cette nouvelle option de ligne de commande, --release:

Nous avons défini une nouvelle option de ligne de commande, --release, qui configure automatiquement le compilateur pour produire des fichiers de classe qui seront liés à une implémentation de la version de plate-forme donnée. Pour les plateformes prédéfinies dans javac, --release N est équivalent à -source N -target N -bootclasspath <bootclasspath-from-N>. (c'est moi qui souligne)

Donc non, ce n'est pas équivalent à -source N -target N. La raison de cet ajout est indiquée dans la section "Motivation":

javac propose deux options de ligne de commande, -source et -target, qui peut être utilisé pour sélectionner la version du Java accepté par le compilateur et la version des fichiers de classe qu'il produit, respectivement. Par défaut, cependant, javac compile avec la version la plus récente des API de la plate-forme. Le programme compilé peut donc accidentellement utiliser des API uniquement disponibles dans la version actuelle de la plate-forme. Ces programmes ne peuvent pas s'exécuter sur des versions plus anciennes de la plate-forme, quelles que soient les valeurs transmises à -source et -target. les options. Il s'agit d'un problème d'utilisation à long terme, car les utilisateurs s'attendent à ce qu'en utilisant ces options, ils obtiennent des fichiers de classe pouvant s'exécuter sur la version de plate-forme spécifiée.

En bref, la spécification des options source et cible ne suffit pas pour la compilation croisée. Étant donné que javac, par défaut, se compile avec la plus récente des API de plate-forme, leur exécution sur les anciennes versions ne peut pas être garantie. Vous devez également spécifier le -bootclasspath option correspondant à l'ancienne version pour une compilation croisée correcte. Cela inclurait la version d'API correcte pour compiler et permettre l'exécution sur une version plus ancienne. Comme il a été très souvent oublié, il a été décidé d'ajouter une option de ligne de commande qui a fait toutes les choses nécessaires pour une compilation croisée correcte.

Lectures complémentaires dans la liste de diffusion et Oracle Docs . Le bug d'origine a été déposé ici . Notez que depuis l'intégration de cette option, les versions JDK sont livrées avec des descriptions des API de plate-forme des versions plus anciennes, mentionnées dans la section "Risques et hypothèses". Cela signifie que vous n'avez pas besoin de l'ancienne version installée sur votre machine pour que la compilation croisée fonctionne.

71
Li357

--release X est plus qu'un simple raccourci vers -source X -target X car -source et -target ne suffit pas pour compiler en toute sécurité vers une version antérieure. Vous devez également définir un -bootclasspath drapeau qui doit correspondre à l'ancienne version (et ce drapeau est souvent oublié). Donc, en Java 9, ils ont fait un seul --release drapeau qui remplace trois drapeaux: -source, -target et -bootclasspath.

Voici donc un exemple de compilation en Java 1.7:

javac --release 7 <source files>

Notez que vous n'avez même pas besoin d'installer JDK 7 sur votre ordinateur. JDK 9 contient déjà les informations nécessaires pour vous empêcher de créer des liens accidentels avec des symboles qui n'existaient pas dans JDK 7.

16
ZhekaKozlov