web-dev-qa-db-ja.com

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

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の単なるショートカットですか?

59
ZhekaKozlov

ではない正確に。

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つのコマンドラインオプションを追加することにしました。

さらに読む メーリングリスト内 および Oracle Docs 。元のバグが報告されました here 。このオプションが統合されて以来、JDKビルドには、「リスクと仮定」のセクションで説明した、古いリリースのプラットフォームAPIの説明がバンドルされていることに注意してください。つまり、クロスコンパイルが機能するためにマシンに古いバージョンをインストールする必要はありません。

71
Li357

--release Xは、-source X -target X-sourceが古いリリースに安全にコンパイルするには不十分であるため、-targetへの単なるショートカット以上のものです。また、古いリリースに対応する必要がある-bootclasspathフラグを設定する必要があります(このフラグはしばしば忘れられます)。したがって、Java 9では、単一の--releaseフラグを作成しました。これは、3つのフラグ-source-targetおよび-bootclasspathの代わりになります。

したがって、これはJava 1.7にコンパイルする例です。

javac --release 7 <source files>

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

16
ZhekaKozlov