Java 9コンパイラの--releaseフラグとは何ですか?


89

Java 9javacには新しいフラグがあり--releaseます:

> javac --help
...

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

フラグ-sourceとはどう違うの-targetですか?それは単なるショートカット-source X -target Xですか?


回答:


113

ではない正確に。

JEP 247:古いプラットフォームバージョン用にコンパイルすると、この新しいコマンドラインオプションが定義されます--release

新しいコマンドラインオプションを定義しました--release。これは、指定されたプラットフォームバージョンの実装に対してリンクするクラスファイルを生成するようにコンパイラを自動的に構成します。であらかじめ定義プラットフォームではjavac--release Nと等価です-source N -target N -bootclasspath <bootclasspath-from-N>。(私の強調)

いいえ、それはと同等ではありません-source N -target N。この追加の理由は、「動機」セクションに記載されています。

javacは、2つのコマンドラインオプションと-sourceを提供します。-targetこれらを使用して、コンパイラが受け入れるJava言語のバージョンと、コンパイラが生成するクラスファイルのバージョンをそれぞれ選択できます。ただし、デフォルトでは、javacプラットフォームAPIの最新バージョンに対してコンパイルされます。したがって、コンパイルされたプログラムは、プラットフォームの現在のバージョンでのみ使用可能なAPIを誤って使用する可能性があります。このようなプログラムは、-sourceおよびに渡された値に関係なく、古いバージョンのプラットフォームでは実行できません-target。オプション。ユーザーは、これらのオプションを使用することで、指定されたプラットフォームバージョンで実行できるクラスファイルを取得できると期待しているため、これは長期的なユーザビリティの問題点です。

つまり、ソースとターゲットのオプションを指定するだけでは、クロスコンパイルには不十分です。javacデフォルトでは、最新のプラットフォームAPIに対してコンパイルされるため、古いバージョンでの実行を保証することはできません。また、-bootclasspath正しくクロスコンパイルするには、古いバージョンに対応するオプションを指定する必要があります。これには、コンパイル対象の正しいAPIバージョンが含まれ、古いバージョンでの実行が可能になります。忘れられがちだったので、正しくクロスコンパイルするために必要なすべてのことを実行する1つのコマンドラインオプションを追加することにしました。

メーリングリストOracleDocsをさらに読んでください。元のバグはここに提出されました。このオプションの統合以降、JDKビルドには、「リスクと前提条件」のセクションで説明した、古いリリースのプラットフォームAPIの説明がバンドルされていることに注意してください。つまり、クロスコンパイルを機能させるために、マシンに古いバージョンをインストールする必要はありません。


1つの疑問は、コードでjdk 9-11の機能を使用でき、それでもJavaランタイム8で実行できるでしょうか。
クリスティアーノ

いいえ、それらはjre 8バイナリには存在しません
ローグ

「PlatformAPI」で何をしますか?バイトコードレベルで何かありますか?または、基盤となるx86プラットフォームまたはOS APIに関連するものですか?
ホセシフエンテス

2
@JoseCifuentes、ここでの「プラットフォームAPI」には、--releaseフラグのないバージョンのJDK APIが与えられます。これは、コンパイルに使用されるJDKから推測されます。これは、通常-source、およびを使用してターゲットとするJDKとは異なります-target。これは、JDKでは導入されていないクラス/メソッドを使用してからターゲットにした場合に、あなたを苦しめる可能性があります。これは、コンパイラが、以前のバージョンよりも後のバージョンで追加されたメソッドのオーバーロードを選択し、バイナリ互換性を黙って破る場合には、非常に微妙です。
オリバーゴンジャ

30

--release Xちょうど近道以上のものです-source X -target Xので、-sourceかつ-target安全に古いリリースにコンパイルするのに十分ではありません。また-bootclasspath、古いリリースに対応する必要があるフラグを設定する必要があります(このフラグは忘れられることがよくあります)。だから、Javaの9に彼らは、単一の作っ--release3つのフラグを置き換えるものですフラグ:-source-target-bootclasspath

したがって、これはJava1.7へのコンパイルの例です。

javac --release 7 <source files>

コンピュータにJDK7をインストールする必要さえないことに注意してください。JDK 9には、JDK7に存在しなかったシンボルへの誤ったリンクを防ぐために必要な情報がすでに含まれています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.