28

最近、Eclipseのjavaコンパイラを使い始めました。これは、標準のjavacよりも大幅に高速であるためです。インクリメンタルコンパイルを実行するので高速だと言われました。しかし、eclispseとsunの両方のコンパイラの「インクリメンタル機能」に関する信頼できるドキュメントが見つからないため、これについてはまだ少しわかりません。Sunのコンパイラは常にすべてのソースファイルをコンパイルし、Eclipseのコンパイラは変更されたファイルとそのような変更の影響を受けるファイルのみをコンパイルするというのは本当ですか?

編集:Eclipseの自動ビルド機能を使用していませんが、代わりに設定しています

-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter

私のアリのビルドのために。

4

4 に答える 4

16

Sunのコンパイラは常にすべてのソースファイルをコンパイルし、Eclipseのコンパイラは変更されたファイルとそのような変更の影響を受けるファイルのみをコンパイルするというのは本当ですか?

私はあなたが両方の点で正しいと信じています。

もちろん、Eclipseにすべてを再コンパイルさせることもできます。

しかし、方程式の他の部分は、AntやMavenなどのJavaビルドツールは、変更されたクラスとそれらの依存クラスのツリーのみをコンパイルできるということです。

編集

Antでは、インクリメンタルコンパイルは2つの方法で実行できます。

  • デフォルトでは、<javac>タスク.javaは対応するファイルのタイムスタンプを比較し.class、対応するターゲット(.class)ファイルよりも新しいソース(.java)ファイル、またはターゲットファイルがまったくないソース(.java)ファイルのみを再コンパイルするようにJavaコンパイラに指示します。 。

  • この<depend>タスクでは、クラス間の依存関係も考慮されます。これは、.classファイルに埋め込まれている依存関係情報を読み取って分析することで決定されます。.classどのファイルが古くなっているかを判断すると、<depend>タスクはそれらを削除するため、次の<javac>タスクがそれらを再コンパイルします。ただし、これは完全に確実なわけではありません。たとえば、ソースコードを大幅に変更すると、<depend>タスクが古い依存関係を分析する可能性があります。また、特定の種類の依存関係(静的定数など)は、.classファイル形式では明らかではありません。

    Antが絶対確実ではない理由を理解するには、ドキュメント<depend>の「制限」セクションをお読みください。

于 2010-04-07T07:34:15.273 に答える
4

Javacは、コマンドラインで名前が付けられているか、依存関係にあり、古くなっているソースファイルのみをコンパイルします。Eclipseには、それが何を意味するのかをよりきめ細かく決定する方法があるかもしれません。

于 2010-12-04T00:45:05.163 に答える
2

Eclipseは確かにこれを行います。また、そのオプションをオンにしている場合は、保存時に実行されます(デフォルトではオンになっています)。sunもこれを行わないようです(テストは非常に簡単です。AがクラスBを使用するメインクラスであるが、BはクラスAを使用しない小さなプロジェクトを作成するだけです。次に、Aを変更してプロジェクトをコンパイルします。もう一度、のタイムスタンプb.classが変更されているかどうかを確認します。

これは、多くのコンパイラが機能する方法です(たとえば、gccも)。antやmakeなどのツールを使用して、プロジェクトが変更された部分のみをコンパイルできます。また、これらのツールは完全ではないことに注意してください。Eclipseが変更を追跡できなくなることがあり、完全な再構築を行う必要があります。

于 2010-04-07T07:30:29.687 に答える
2

私がここで聞いたことを言い換えて、私のような怠惰な人々のためにそれを言い換えます:

antのjavacタスクを使用してインクリメンタルビルドを実現できますが、dependタスクを使用して、変更した.javaの.classファイルをクリアする必要があります。また、javacタスクでincludesステートメントを指定しないままにしないでください。(javacタスクでsrcパスのみを指定し、インクルードを指定しないままにすると、javacは検出したすべてのソースを再コンパイルします。)

これが私の依存タスクとjavacタスクです。標準のOracleJavaコンパイラでは、変更した.javaファイルのみがコンパイルされます。お役に立てれば!

<depend srcdir="JavaSource" destdir="${target.classes}" cache="${dependencies.dir}" closure="yes">
    <classpath refid="compiler.classpath" />
    <include name="**/*.java"/>
</depend>

<javac destdir="${target.classes}" debug="true" debuglevel="${debug.features}" optimize="${optimize.flag}" fork="yes" deprecation="no" source="1.6" target="1.6" encoding="UTF-8" includeantruntime="no">
    <classpath refid="compiler.classpath"/>
    <src path="JavaSource"/>
    <include name="**/*.java" />   <!-- This enables the incremental build -->
</javac>
于 2013-11-25T14:27:08.480 に答える