Javaクラスとインタフェースの定義を読み取り、それらをバイト・コードとクラス・ファイルにコンパイルします。
javac [ options ] [ sourcefiles ] [ classes] [ @argfiles ]
引数を指定する順序は任意です。
コマンド行オプション。 「オプション」を参照してください。
コンパイルされる1つ以上のソース・ファイル(MyClass.javaなど)。
注釈の処理対象となる1つ以上のクラス(MyPackage.MyClassなど)。
オプションとソース・ファイルを一覧表示した1つ以上のファイル。 このファイルの中では、-Jオプションは指定できません。 「コマンド行引数ファイル」を参照してください。
javacコマンドは、Javaプログラミング言語で記述されたクラスとインタフェースの定義を読み取り、バイト・コードのクラス・ファイルにコンパイルします。 また、javacコマンドは、Javaソース・ファイルおよびクラス内の注釈も処理できます。
ソース・コードのファイル名をjavacに渡すには、2つの方法があります。
ソース・ファイルの数が少ない場合は、ファイル名をコマンド行に指定します。
ソース・ファイルの数が多い場合は、ファイル名を空白または改行で区切って、1つのファイルに一覧表示します。 javacコマンドで、先頭に記号(@)を付けたリスト・ファイル名を使用します。
ソース・コードのファイル名には.java接尾辞が必要で、クラスのファイル名には.class接尾辞が必要であり、ソース・ファイルとクラス・ファイルのどちらも、クラスを識別するルート名が必要です。 たとえば、MyClassという名前のクラスは、MyClass.javaというソース・ファイルに記述され、MyClass.classというバイトコード・クラス・ファイルにコンパイルされます。
内部クラスが定義されていると、追加のクラス・ファイルが生成されます。 これらのクラス・ファイルの名前は、MyClass$MyInnerClass.classのように、内部クラス名と外部クラス名を組み合わせたものになります。
ソース・ファイルは、パッケージ・ツリーを反映したディレクトリ・ツリーに配置します。 たとえば、すべてのソース・ファイルを\workspaceに置いている場合、com.mysoft.mypack.MyClassのソース・コードは\workspace\com\mysoft\mypack\MyClass.javaの/workspaceに置いてください。
デフォルトでは、コンパイラは、各クラス・ファイルを対応するソース・ファイルと同じディレクトリに置きます。 -dオプションで別の出力先ディレクトリを指定できます。
コンパイラには、現在の開発環境でサポートされている一連の標準オプションがあります。 これ以外の非標準オプションは、現在の仮想マシンおよびコンパイラの実装に固有のオプションで、将来に変更される可能性があります。 非標準オプションは、-Xオプションで始まります。
「クロスコンパイル・オプション」も参照してください
「非標準オプション」も参照してください
注釈プロセッサに渡すオプションを指定します。 これらのオプションは、javacが直接解釈するのではなく、それぞれのプロセッサによって使用できるようにします。 key値はドット(.)によって区切られた1つ以上の識別子にすべきです。
ユーザーのクラス・ファイルおよび(オプションで)注釈プロセッサやソース・ファイルの検索場所を指定します。 このクラス・パスはCLASSPATH環境変数のユーザー・クラス・パスをオーバーライドします。 CLASSPATH、-cp、-classpathのいずれも指定されていない場合、ユーザー・クラス・パスは、現在のディレクトリになります。 「クラス・パスの設定」を参照してください。
-sourcepathオプションが指定されていない場合は、ソース・ファイルもユーザー・クラス・パスから検索されます。
-processorpathオプションが指定されていない場合は、注釈プロセッサもユーザー・クラス・パスから検索されます。
インストールされた拡張機能の位置をオーバーライドします。
承認された標準パスの位置をオーバーライドします。
クラス・ファイルの出力先ディレクトリを設定します。 そのディレクトリはjavacによって作成されないため、すでに存在している必要があります。 クラスがパッケージに含まれる場合、javacは、パッケージ名を反映したサブディレクトリにクラス・ファイルを置き、必要に応じてディレクトリを作成します。
-d C:\myclassesと指定し、クラスの名前がcom.mypackage.MyClassである場合、クラス・ファイルはC:\myclasses\com\mypackage\MyClass.classになります。
-dオプションが指定されていない場合、javacは各クラス・ファイルを、その生成元のソース・ファイルと同じディレクトリ内に置きます。
ノート: -dオプションで指定したディレクトリはユーザー・クラス・パスに自動的には追加されません。
非推奨のメンバーやクラスの使用またはオーバーライドのたびに説明を表示します。 -deprecationオプションが指定されていない場合、javacは、非推奨のメンバーやクラスを使用またはオーバーライドしているソース・ファイルのサマリーを表示します。 -deprecationオプションは-Xlint:deprecationの省略表記です。
ソース・ファイルのエンコーディング名(EUC-JPやUTF-8など)を設定します。 -encodingオプションが指定されていない場合は、プラットフォームのデフォルト・コンバータが使われます。
承認された標準パスの位置をオーバーライドします。
extディレクトリの位置をオーバーライドします。 directories変数は、コロンで区切ったディレクトリのリストです。 指定したディレクトリ内の各JARファイルから、クラス・ファイルが検索されます。 見つかったすべてのJARファイルがクラス・パスの一部になります。
クロスコンパイル(異なるJavaプラットフォーム実装のブートストラップ・クラスおよび拡張機能クラスに対するクラスのコンパイル)を行う場合、このオプションには拡張クラスが格納されているディレクトリを指定します。 詳細は、「クロスコンパイル・オプション」を参照してください。
ローカル変数を含むすべてのデバッグ情報を生成します。 デフォルトでは、行番号およびソース・ファイル情報だけが生成されます。
デバッグ情報を生成しません。
カンマで区切られたキーワードのリストによって指定された、特定の種類のデバッグ情報のみを生成します。 次のキーワードが有効です。
ソース・ファイルのデバッグ情報。
行番号のデバッグ情報。
ローカル変数のデバッグ情報。
標準オプションの形式を出力します。
暗黙的にロードされたソース・ファイルに対するクラス・ファイルの生成を制御します。 クラス・ファイルを自動生成するには、-implicit:classを使用します。 クラス・ファイルの生成を抑制するには、-implicit:noneを使用します。 このオプションが指定されなかった場合、デフォルト動作は、クラス・ファイルの自動生成になります。 その場合、そのようなクラス・ファイルが生成されたときに注釈処理も実行されると、コンパイラから警告が発行されます。 -implicitオプションが明示的に設定された場合には、警告は発行されません。 「型の検索」を参照してください。
Java仮想マシン(JVM)にoptionを渡します(optionは、Javaランチャのリファレンス・ページに記載されているいずれかのオプション)。 たとえば、-J-Xms48mと指定すると、スタートアップ・メモリーは48Mバイトに設定されます。 java(1)を参照してください。
ノート: CLASSPATH、-classpath、-bootclasspathおよび-extdirsオプションは、javacを実行するために使用するクラスを指定しません。 これらのオプションや変数でコンパイラ実装をカスタマイズしようとすることは危険であり、目的が実現されないことがあります。 コンパイラ実装をカスタマイズする必要がある場合は、-Jオプションを使用して、オプションを基礎となるJavaランチャに渡してください。
警告メッセージを無効にします。 このオプションは、-Xlint:noneオプションと同じように動作します。
Reflection APIのメソッドjava.lang.reflect.Executable.getParametersが取得できるように、コンストラクタやメソッドの仮パラメータ名を、生成されたクラス・ファイルに格納します。
注釈処理とコンパイルが実行されるかどうかを制御します。-proc:noneは、注釈処理なしでコンパイルが実行されることを意味します。-proc:onlyは、注釈処理のみが実行され、後続のコンパイルは実行されないことを意味します。
実行する注釈プロセッサの名前。 これを指定した場合、デフォルトの検索処理は省略されます。
注釈プロセッサを見つける場所を指定します。 このオプションが使用されていない場合、クラス・パスでプロセッサが検索されます。
生成されたソース・ファイルの格納先となるディレクトリを指定します。 そのディレクトリはjavacによって作成されないため、すでに存在している必要があります。 クラスがパッケージに含まれる場合、コンパイラは、パッケージ名を反映したサブディレクトリにソース・ファイルを置き、必要に応じてディレクトリを作成します。
-s C:\mysrcと指定し、クラスの名前がcom.mypackage.MyClassである場合、ソース・ファイルはC:\mysrc\com\mypackage\MyClass.javaに格納されます。
受け付けるソース・コードのバージョンを指定します。 releaseには次の値を指定できます。
このコンパイラでは、Java SE 1.3以降に導入されたアサーション、ジェネリックス、またはその他の言語機能をサポートしません。
Java SE 1.4で導入された、アサーションを含むコードを受け付けます。
Java SE 5で導入されたジェネリックスおよびその他の言語機能を含むコードを受け付けます。
1.5と同義です。
Java SE 6では言語に対する変更は導入されませんでした。 ただし、ソース・ファイル内のエンコーディング・エラーが、Java Platform, Standard Editionの以前のリリースのような警告ではなく、エラーとして報告されるようになりました。
1.6と同義です。
Java SE 7で導入された機能を含むコードを受け付けます。
1.7と同義です。
これがデフォルト値です。 Java SE 8で導入された機能を含むコードを受け付けます。
1.8と同義です。
クラスまたはインタフェースの定義を検索するソース・コード・パスを指定します。 ユーザー・クラス・パスと同様に、ソース・パスのエントリは、Oracle Solarisではコロン(:)で、Windowsではセミコロンで区切り、ディレクトリ、JARアーカイブまたはZIPアーカイブを指定できます。 パッケージを使用している場合は、ディレクトリまたはアーカイブ内のローカル・パス名がパッケージ名を反映していなければなりません。
ノート: クラス・パスを通じて見つかったクラスは、それらのソース・ファイルも見つかった場合にコンパイルできます。 「型の検索」を参照してください。
ロードされる各クラスおよびコンパイルされる各ソース・ファイルに関する情報を含む詳細出力を使用します。
リリース情報を出力します。
警告が発生したらコンパイルを終了します。
非標準オプションに関する情報を表示して終了します。
デフォルトでは、クラスのコンパイルは、javacが付属するプラットフォームのブートストラップ・クラスおよび拡張機能クラスに対して行われます。 ただし、javacでは、異なるJavaプラットフォーム実装のブートストラップ・クラスおよび拡張機能クラスに対して、クラスのコンパイルを行うクロスコンパイルもサポートしています。 クロスコンパイルを行う場合は、-bootclasspathおよび-extdirsオプションを使用することが重要です。
指定されたリリースの仮想マシンをターゲットにしたクラス・ファイルを生成します。 クラス・ファイルは、指定されたターゲット以降のリリースでは動作しますが、それより前のリリースのVMでは動作しません。 有効なターゲットは、1.1、1.2、1.3、1.4、1.5 (5も可)、1.6 (6も可)、1.7 (7も可)および1.8 (8も可)です。
-targetオプションのデフォルトは、-sourceオプションの値によって決まります。
-sourceオプションが指定されていない場合、-targetオプションの値は1.8になります。
-sourceオプションが1.2である場合、-targetオプションの値は1.4になります。
-sourceオプションが1.3である場合、-targetオプションの値は1.4になります。
-sourceオプションが1.5である場合、-targetオプションの値は1.8になります。
-sourceオプションが1.6である場合、-targetオプションの値は1.8になります。
-sourceオプションが1.7である場合、-targetオプションの値は1.8になります。
-sourceオプションのその他の値の場合、-targetオプションの値は-sourceオプションの値になります。
指定された一連のブート・クラスに対してクロスコンパイルを行います。 ユーザー・クラス・パスと同様に、ブート・クラスパスのエントリはコロン(:)で区切り、ディレクトリ、JARアーカイブまたはZIPアーカイブを指定できます。
JDK 8から、javacコンパイラはCompactプロファイルをサポートしています。 Compactプロファイルによって、Javaプラットフォーム全体を必要としないアプリケーションをデプロイし、小さなフットプリントで実行できます。 Compactプロファイル機能は、アプリ・ストアからのアプリケーションのダウンロード時間を短縮するために使用できます。 この機能は、JREをバンドルするJavaアプリケーションのコンパクトなデプロイを可能にします。 この機能は、小さなデバイスでも役立ちます。
サポートされるプロファイル値はcompact1、compact2およびcompact3です。 これらは追加のレイヤーです。 大きい番号の各Compactプロファイルには、小さい番号名のプロファイルのすべてのAPIが含まれます。
Compactプロファイルを使用すると、このオプションはコンパイル時にプロファイル名を指定します。 たとえば:
javac -profile compact1 Hello.java
javacは、指定されたプロファイルにないJava SE APIを使用するソース・コードをコンパイルしません。 これは、そのようなソース・コードのコンパイルを試みた結果のエラー・メッセージの例です。
cd jdk1.8.0/bin ./javac -profile compact1 Paint.java Paint.java:5: error: Applet is not available in profile 'compact1' import java.applet.Applet;
この例では、ソースでAppletクラスを使用しないように変更して、エラーを修正できます。 -profileオプションを付けないでコンパイルすることで、エラーを修正することもできます。 これにより、コンパイルはフル・セットのJava SE APIに対して実行されます。 (CompactプロファイルにはAppletクラスが含まれません。)
Compactプロファイルによってコンパイルする代替の方法は、-bootclasspathオプションを使用して、プロファイルのイメージを指定するrt.jarファイルへのパスを指定することです。 かわりに-profileオプションを使用する場合、コンパイル時にシステム上にプロファイル・イメージが存在する必要がありません。 これはクロスコンパイル時に役立ちます。
ブートストラップ・クラス・パスに接尾辞を追加します。
ブートストラップ・クラス・パスに接頭辞を追加します。
ブートストラップ・クラス・ファイルの位置をオーバーライドします。
group [/access]特定のグループのチェックを有効または無効にします。ここでgroupは、accessibility、syntax、reference、htmlまたはmissingのいずれかの値です。 これらのチェックのグループの詳細は、javadocコマンドの-Xdoclintオプションを参照してください。 javacコマンドで-Xdoclintオプションはデフォルトで無効にされています。
変数accessは、-Xdoclintオプションでチェックするクラスとメンバーの最低の可視性レベルを指定します。 これは、(最大から最低の可視性の順序で)public、protected、packageおよびprivateの値のいずれかになります。 たとえば、次のオプションは、protected以上のアクセス・レベル(protected、packageおよびpublicを含む)を持つクラスおよびメンバー(すべてのチェックのグループで)をチェックします。
-Xdoclint:all/protected
次のオプションは、アクセス・レベルがpackage以上(packageとpublicを含む)のクラスとメンバーのHTMLエラーをチェックしないことを除いて、すべてのアクセス・レベルのすべてのグループのチェックを有効にします。
-Xdoclint:all,-html/package
すべてのグループのチェックを無効にします。
/access]すべてのグループのチェックを有効にします。
推奨されるすべての警告を有効にします。 このリリースでは、利用可能なすべての警告を有効にすることが推奨されています。
推奨されるすべての警告を有効にします。 このリリースでは、利用可能なすべての警告を有効にすることが推奨されています。
すべての警告を無効にします。
警告名を無効にします。 このオプションで無効にできる警告のリストについては、「-Xlintオプションによる警告の有効化と無効化」を参照してください。
警告名を無効にします。 -Xlintオプションで無効にできる警告のリストを取得するには、「-Xlintオプションによる警告の有効化と無効化」を参照してください。
印刷するエラーの最大数を設定します。
印刷する警告の最大数を設定します。
コンパイラのメッセージを、指定されたファイルに送ります。 デフォルトでは、コンパイラのメッセージはSystem.errに送られます。
ある型に対してソース・ファイルとクラス・ファイルの両方が見つかった場合、そのどちらのファイルを読み取るべきかを指定します。 (「型の検索」を参照)。 -Xprefer:newerオプションを使用した場合、ある型に対するソース・ファイルとクラス・ファイルの新しい方が読み取られます(デフォルト)。 -Xprefer:sourceオプションを使用した場合、ソース・ファイルが読み取られます。 SOURCEの保存ポリシーを使用して宣言された注釈に任意の注釈プロセッサがアクセスできるようにする場合は、-Xprefer:sourceを使用してください。
javacがpackage-info.javaファイルからpackage-info.classファイルを生成するかどうかを制御します。 このオプションのmode引数には次を指定できます。
すべてのpackage-info.javaファイルに対して、常にpackage-info.classファイルを生成します。 このオプションは、各.javaファイルに対応する.classファイルがあることをチェックするAntなどのビルド・システムを使用する場合に役立つことがあります。
package-info.javaに注釈が含まれる場合にのみ、package-info.classファイルを生成します。 package-info.javaにコメントのみが含まれる場合は、package-info.classファイルを生成しません。
ノート: package-info.javaファイルのすべてのノートにRetentionPolicy.SOURCEがある場合、package-info.classファイルは生成されますが、空になります。
package-info.javaにRetentionPolicy.CLASSまたはRetentionPolicy.RUNTIMEのある注釈が含まれる場合にのみ、package-info.classファイルを生成します。
指定された型のテキスト表現をデバッグ目的で出力します。 注釈処理もコンパイルも実行しません。 出力形式は変更される可能性があります。
ある特定のプロセッサが処理を依頼されている注釈に関する情報を出力します。
初回および後続の注釈処理のラウンドに関する情報を出力します。
-Xlint:nameオプションを使用して警告nameを有効にします。nameは次のいずれかの警告名です。 -Xlint:-name:オプションを使用して警告を無効にできることに注意してください。
不要で冗長なキャストについて警告します。たとえば:
String s = (String) "Hello!"
クラス・ファイルの内容に関する問題について警告します。
非推奨項目の使用について警告します。たとえば:
java.util.Date myDate = new java.util.Date(); int currentDay = myDate.getDay();
メソッドjava.util.Date.getDayは、JDK 1.1以降、非推奨になりました。
@deprecated Javadocコメントでドキュメント化されているが、@Deprecated注釈が付いていない項目について警告します。たとえば:
/**
* @deprecated As of Java SE 7, replaced by {@link #newMethod()}
*/
public static void deprecatedMethood() { }
public static void newMethod() { }
定整数0による除算について警告します。たとえば:
int divideByZero = 42 / 0;
if文の後が空の文であることを警告します。たとえば:
class E {
void m() {
if (true) ;
}
}
fall-through caseのswitchブロックをチェックし、検出されたものに対して警告メッセージを表示します。 Fall-through caseは、switchブロック内の最後のcaseを除くcaseです。このコードにはbreak文は含まれず、コードの実行をそのcaseから次のcaseへ移動できます。 たとえば、このswitchブロック内のcase 1ラベルに続くコードは、break文で終わっていません。
switch (x) {
case 1:
System.out.println("1");
// No break statement here.
case 2:
System.out.println("2");
}
このコードのコンパイル時に-Xlint:fallthroughオプションが使用されていた場合、コンパイラは該当するcaseの行番号とともに、caseにfall-throughする可能性があることを示す警告を発行します。
正常に完了できないfinally節について警告します。たとえば:
public static int m() {
try {
throw new NullPointerException();
} catch (NullPointerException(); {
System.err.println("Caught NullPointerException.");
return 1;
} finally {
return 0;
}
}
この例では、コンパイラはfinallyブロックに関する警告を生成します。 intメソッドが呼び出されると、0の値が返されます。 finallyブロックは、tryブロックが終了すると実行されます。 この例では、catchブロックに制御が移されると、intメソッドは終了します。 ただし、finallyブロックは実行される必要があるため、制御がすでにこのメソッドの外部に移されていても、このブロックは実行されます。
コマンド行オプションの使用に関する問題について警告します。 「クロスコンパイル・オプション」を参照してください。
メソッドのオーバーライドに関する問題について警告します。 たとえば、次の2つのクラスがあるとします。
public class ClassWithVarargsMethod {
void varargsMethod(String... s) { }
}
public class ClassWithOverridingMethod extends ClassWithVarargsMethod {
@Override
void varargsMethod(String[] s) { }
}
コンパイラは次のような警告を生成します。
warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod overrides varargsMethod(String...) in ClassWithVarargsMethod; overriding method is missing '...'
コンパイラがvarargsメソッドを検出すると、varargsの仮パラメータを配列に変換します。 メソッドClassWithVarargsMethod.varargsMethodでは、コンパイラはvarargsの仮パラメータString... sを仮パラメータString[] s(配列)に変換しますが、この配列はメソッドClassWithOverridingMethod.varargsMethodの仮パラメータと一致します。 その結果、この例ではコンパイルが行われます。
コマンド行のクラス・パス、ソース・パスおよびその他のパスとして指定された無効なパス要素と存在しないパス・ディレクトリについて警告します。 このような警告は、@SuppressWarnings注釈では抑制できません。たとえば:
javac -Xlint:path -classpath C:\nonexistentpath Example.java
注釈処理に関する問題について警告します。 コンパイラがこの警告を生成するのは、注釈を含むクラスがあり、そのタイプの例外を処理できない注釈プロセッサを使用している場合です。 たとえば、次のものは簡単な注釈プロセッサです:
ソース・ファイルAnnocProc.java:
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import.javaz.lang.model.element.*;
@SupportedAnnotationTypes("NotAnno")
public class AnnoProc extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){
return true;
}
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}
ソース・ファイルAnnosWithoutProcessors.java:
@interface Anno { }
@Anno
class AnnosWithoutProcessors { }
次のコマンドは、注釈プロセッサAnnoProcをコンパイルしたあと、ソース・ファイルAnnosWithoutProcessors.javaに対してこの注釈プロセッサを実行します。
javac AnnoProc.java javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java
ソース・ファイルAnnosWithoutProcessors.javaに対して注釈プロセッサを実行すると、コンパイラは次の警告を生成します。
warning: [processing] No processor claimed any of these annotations: Anno
この問題を解決するには、AnnosWithoutProcessorsクラスで定義および使用されている注釈の名前をAnnoからNotAnnoに変更します。
raw型に対する未チェック操作について警告します。 次の文では、rawtypes警告が生成されます。
void countElements(List l) { ... }
次の例は、rawtypes警告が生成されません。
void countElements(List<?> l) { ... }
Listはraw型です。 ただし、List<?>はバインドなしのパラメータ化されたワイルドカード型です。 Listはパラメータ化されたインタフェースなので、必ずその型引数を指定するようにしてください。 この例では、Listの仮引数はバインドなしのワイルドカード(?)を使用してその仮型パラメータとして指定されています。つまり、countElementsメソッドはListインタフェースの任意のインスタンス化を受け入れることができます。
serialVersionUID定義が直列化可能クラスにないことを警告します。たとえば:
public class PersistentTime implements Serializable
{
private Date time;
public PersistentTime() {
time = Calendar.getInstance().getTime();
}
public Date getTime() {
return time;
}
}
コンパイラで次のような警告が生成されます。
warning: [serial] serializable class PersistentTime has no definition of serialVersionUID
直列化可能クラスがserialVersionUIDという名前のフィールドを明示的に宣言しない場合、直列化ランタイム環境は「Javaオブジェクト直列化仕様」で説明されているように、クラスの様々な側面に基づいて、クラスのserialVersionUIDのデフォルト値を計算します。 ただし、すべての直列化可能クラスでserialVersionUID値を明示的に宣言することを強くお薦めします。これは、デフォルトのserialVersionUID値の計算のプロセスが、コンパイラの実装によって異なる可能性のあるクラスの詳細にきわめて影響を受けやすく、直列化復元中に予期しないInvalidClassExceptionsが発生する可能性があるためです。 様々なjavaコンパイラ実装間でserialVersionUID値の一貫性を確保にするには、直列化可能クラスでserialVersionUID値を明示的に宣言しなければいけません。
staticの使用に関する問題について警告します。たとえば:
class XLintStatic {
static void m1() { }
void m2() { this.m1(); }
}
コンパイラで次のような警告が生成されます。
warning: [static] static method should be qualified by type name, XLintStatic, instead of by an expression
この問題を解決するために、次のようにstaticメソッドm1を呼び出すことができます。
XLintStatic.m1();
あるいは、staticキーワードをメソッドm1の宣言から削除することもできます。
try-with-resources文を含む、tryブロックの使用に関する問題について警告します。 たとえば、tryブロックで宣言されたリソースacが使用されていないため、次の文に対して警告が生成されます。
try ( AutoCloseable ac = getResource() ) { // do nothing}
Java言語仕様で指定されている未チェック変換警告の詳細を示します。たとえば:
List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning
型の消去中に、型ArrayList<Number>およびList<String>はそれぞれArrayListおよびListになります。
lsコマンドはパラメータ化された型List<String>を持ちます。 lによって参照されているListがlsに代入されている場合、コンパイラは非チェック警告を生成します。 コンパイル時に、コンパイラとJVMはlがList<String>型を表すかどうかを判断できません。 この場合、lはList<String>型を表しません。 結果として、ヒープ汚染が発生します。
ヒープ汚染状態が発生するのは、Listオブジェクトl (そのstatic型はList<Number>)が別のListオブジェクトls (異なるstatic型List<String>を持つ)に代入される場合です。 しかし、コンパイラはこの代入をいまだに許可しています。 この代入を許可する必要があるのは、ジェネリックスをサポートしないJava SEのリリースとの下位互換性を確保するためです。 型消去のために、List<Number>とList<String>はListになります。 その結果、コンパイラはオブジェクトl (Listというraw型を持つ)をオブジェクトlsに代入することを許可します。
可変引数(varargs)メソッド、特に非具象化可能引数を含むメソッドの安全でない使用を警告します。たとえば:
public class ArrayBuilder {
public static <T> void addToList (List<T> listArg, T... elements) {
for (T x : elements) {
listArg.add(x);
}
}
}
ノート: 非具象化可能型は、実行時に型情報を完全に使用できない型です。
コンパイラは、メソッドArrayBuilder.addToListの定義に関する次の警告を生成します。
warning: [varargs] Possible heap pollution from parameterized vararg type T
コンパイラがvarargsメソッドを検出すると、varargs仮パラメータを配列に変換します。 しかし、Javaプログラミング言語では、パラメータ化された型の配列の作成は許可されません。 メソッドArrayBuilder.addToListでは、コンパイラはvarargsの仮パラメータT... elements要素を仮パラメータT[] elements要素(配列)に変換します。 しかし、型消去のために、コンパイラはvarargsの仮パラメータをObject[]要素に変換します。 その結果、ヒープ汚染が発生する可能性があります。
javacコマンドを短くしたり簡潔にしたりするために、javacコマンドへの引数(-Jオプションを除く)を含んだ1つ以上のファイルを指定できます。 これにより、任意のオペレーティング・システムで、任意の長さのjavacコマンドを作成できます。
引数ファイルには、javacのオプションとソース・ファイル名を自由に組み合わせて記述できます。 ファイル内の引数は、空白文字または改行文字で区切ることができます。 ファイル名に空白が含まれている場合は、そのファイル名全体を二重引用符で囲みます。
引数ファイル内のファイル名は、現在のディレクトリから相対的で、引数ファイルの位置からではありません。 これらのリストでは、ワイルドカード(*)を使用すること(*.javaと指定するなど)はできません。 ファイルを再帰的に解釈するための記号(@)の使用はサポートされていません。 -Jオプションはサポートされていません(それらはランチャに渡され、それが引数ファイルをサポートしていないため)。
javacコマンドを実行するときに、各引数ファイルのパスとファイル名の先頭にアット記号(@)を付けて渡します。 javacコマンドは、アット記号(@)で始まる引数を検出すると、そのファイルの内容を引数リストに展開します。
すべてのjavac引数を保持するargfileという名前の単一の引数ファイルを使用できます。
javac @argfile
この引数ファイルには、例2で示されている両方のファイルの内容を格納できます。
たとえば、javacオプション用に1ファイル、ソース・ファイル名用に1ファイルというように、2つの引数ファイルを作成できます。 次のリストでは、行の継続文字を使用していないことに注意してください。
次を含むoptionsというファイルを作成します。
-d classes -g -sourcepath C:\java\pubs\ws\1.3\src\share\classes
次を含むclassesというファイルを作成します。
MyClass1.java MyClass2.java MyClass3.java
次に、次のようにjavacコマンドを実行します。
javac @options @classes
引数ファイルにはパスを指定できますが、ファイル内のすべてのファイル名は、現在の作業ディレクトリに相対的になります(path1やpath2でなく)。
javac @path1/options @path2/classes
javacコマンドが注釈処理を直接サポートしているため、個別の注釈処理コマンドのaptを使用する必要がなくなりました。
注釈プロセッサのAPIは、javax.annotation.processingおよびjavax.lang.modelパッケージとそのサブパッケージ内に定義されています。
-proc:noneオプションによって注釈処理が無効化されないかぎり、コンパイラは使用可能なすべての注釈プロセッサを検索します。 検索パスは-processorpathオプションを使用して指定できます。 パスが指定されていない場合は、ユーザー・クラス・パスが使用されます。 プロセッサの検索は、検索パス上のMETA-INF/services/javax.annotation.processing.Processorという名前のサービス・プロバイダ構成ファイルを使用して行われます。 このようなファイルには、使用するすべての注釈プロセッサの名前を、1行に1つずつ含めてください。 または、-processorオプションを使用してプロセッサを明示的に指定することもできます。
コンパイラは、コマンド行のソース・ファイルやクラスをスキャンすることで、どのような注釈が存在しているかを確認し終わると、プロセッサに対して問合わせを行い、それらのプロセッサがどの注釈を処理できるのかを確認します。 一致するものが見つかった場合、そのプロセッサが呼び出されます。 各プロセッサは、自身が処理する注釈を要求できます。その場合、それらの注釈に対する別のプロセッサを見つける試みは行われません。 すべての注釈が要求された後に、コンパイラは追加のプロセッサを検索しません。
いずれかのプロセッサによって新しいソース・ファイルが生成されると、もう1ラウンド注釈処理が行われます。新しく生成されたソース・ファイルがスキャンされ、注釈が前と同じように処理されます。 以前のラウンドで呼び出されたプロセッサはすべて、後続のすべてのラウンドでも呼び出されます。 これが、新しいソース・ファイルが生成されなくなるまで続きます。
あるラウンドで新しいソース・ファイルが生成されなかった場合、注釈プロセッサがあと1回だけ呼び出され、残りの処理を実行する機会が与えられます。 最後に、-proc:onlyオプションが使用されなければ、コンパイラは、元のソース・ファイルと生成されたすべてのソース・ファイルをコンパイルします。
コンパイラは、一連のソース・ファイルをコンパイルする際に、別のソース・ファイルを暗黙的にロードしなければならない場合があります。 「型の検索」を参照してください。 そのようなファイルは、現時点では注釈処理の対象になりません。 デフォルトでは、注釈処理が実行され、かつ暗黙的にロードされたソース・ファイルが1つでもコンパイルされた場合にコンパイラは警告を発行します。 -implicitオプションは、警告を抑制する方法を提供します。
ソース・ファイルをコンパイルするため、コンパイラは型に関する情報を必要とする場合がありますが、コマンド行で指定されるソース・ファイルに型の定義がありません。 コンパイラは、ソース・ファイルで使われているクラスまたはインタフェース、拡張されているクラスまたはインタフェース、あるいは実装されているクラスまたはインタフェースすべてについて、型の情報を必要とします。 これには、ソース・ファイルで明示的には言及されていなくても、継承を通じて情報を提供するクラスとインタフェースも含まれます。
たとえば、java.applet.Appletサブクラスを作成する場合、Appletの祖先のクラス(java.awt.Panel、java.awt.Container、java.awt.Componentおよびjava.lang.Object)も使用していることになります。
コンパイラは、型の情報が必要になると、その型を定義しているソース・ファイルまたはクラス・ファイルを探します。 まず、ブートストラップ・クラスと拡張機能クラスを検索し、続いてユーザー・クラス・パス(デフォルトではカレント・ディレクトリ)を検索します。 ユーザー・クラス・パスは、CLASSPATH環境変数を設定するか、または-classpathオプションを使用して定義します。
-sourcepathオプションを設定した場合、コンパイラは指定したパスでソース・ファイルを検索します。 そうでない場合、コンパイラは、ユーザー・クラス・パスでクラス・ファイルとソース・コード・ファイルの両方を検索します。
-bootclasspathオプションと-extdirsオプションを使用すると、別のブートストラップ・クラスや拡張機能クラスを指定できます。 「クロスコンパイル・オプション」を参照してください。
型の検索に成功したときに得られる結果は、クラス・ファイル、ソース・ファイル、またはその両方である場合があります。 両方が見つかった場合、そのどちらを使用すべきかを-Xpreferオプションでコンパイラに指示できます。 newerが指定された場合、コンパイラは2つのファイルの新しい方を使用します。 sourceが指定された場合、コンパイラはソース・ファイルを使用します。 デフォルトはnewerです。
型の検索自体によって、または-Xpreferオプションが設定された結果として、必要な型のソース・ファイルが見つかった場合、コンパイラはそのソース・ファイルを読み取り、必要な情報を取得します。 デフォルトで、コンパイラは、ソース・ファイルもコンパイルします。 -implicitオプションを使えばその動作を指定できます。 noneを指定した場合、ソース・ファイルのクラス・ファイルは生成されません。 classを指定した場合、ソース・ファイルのクラス・ファイルが生成されます。
コンパイラは、注釈処理の完了後に、ある型情報の必要性を認識しない場合があります。 型情報がソース・ファイル内に見つかり、かつ-implicitオプションが指定されていない場合、コンパイラは、そのファイルが注釈処理の対象とならずにコンパイルされることを警告します。 この警告を無効にするには、(そのファイルが注釈処理の対象となるように)そのファイルをコマンド行に指定するか、あるいはそのようなソース・ファイルに対してクラス・ファイルを生成すべきかどうかを-implicitオプションを使って指定します。
javacコマンドは、javax.toolsパッケージ内のクラスとインタフェースによって定義される新しいJava Compiler APIをサポートします。
コマンド行引数を指定したかのようにコンパイルするには、次の構文を使用します。
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
例では、診断を標準出力ストリームに書き込み、コマンド行から呼び出された場合にjavacが提供する終了コードを返します。
javax.tools.JavaCompilerインタフェースで他のメソッドを使えば、診断の処理やファイルの読取り元/書込み先の制御などを行えます。
ノート: このAPIは下位互換性のためにのみ保持されています。 新しいコードでは、新しいJava Compiler APIを使用してください。
com.sun.tools.javac.Mainクラスには、プログラム内からコンパイラを呼び出すためのstaticメソッドが2つ用意されています。
public static int compile(String[] args); public static int compile(String[] args, PrintWriter out);
argsパラメータは、一般にコンパイラに渡される任意のコマンド行引数を表します。
outパラメータは、コンパイラの診断の出力先を示します。
return値は、javacのexit値と同等です。
ノート: 名前がcom.sun.tools.javacで始まるパッケージ(com.sun.tools.javacのサブパッケージ)に含まれるその他のすべてのクラスやメソッドは、厳密に内部用であり、いつでも変更される可能性があります。
この例では、greetingsディレクトリ内のHello.javaソース・ファイルをコンパイルする方法を示しています。 Hello.javaに定義されているクラスは、greetings.Helloと呼ばれます。 greetingsディレクトリは、ソース・ファイルとクラス・ファイルの両方のパッケージ・ディレクトリで、現在のディレクトリのすぐ下にあります。 これにより、デフォルトのユーザー・クラス・パスを使用できます。 また、-dオプションを使用して別の出力先ディレクトリを指定する必要もありません。
Hello.java内のソース・コード:
package greetings;
public class Hello {
public static void main(String[] args) {
for (int i=0; i < args.length; i++) {
System.out.println("Hello " + args[i]);
}
}
}
greetings.Helloのコンパイル:
javac greetings/Hello.java
greetings.Helloを実行します。
java greetings.Hello World Universe Everyone Hello World Hello Universe Hello Everyone
この例では、greetingsパッケージ内のAloha.java、GutenTag.java、Hello.javaおよびHi.javaソース・ファイルをコンパイルします。
C:\>javac greetings\*.java C:\>dir greetings Aloha.class GutenTag.class Hello.class Hi.class Aloha.java GutenTag.java Hello.java Hi.java
前の例のいずれかのソース・ファイルの変更後、それを再コンパイルします。
C:\>cd \examples C:\>javac greetings\Hi.java
greetings.Hiは、greetingsパッケージ内の他のクラスを参照しているため、コンパイラはこれらのその他のクラスを探す必要があります。 前の例は、デフォルトのユーザー・クラス・パスが、パッケージ・ディレクトリを含むディレクトリであるため機能します。 現在のディレクトリに関係なく、このファイルを再コンパイルする場合、CLASSPATHを設定して、例のディレクトリをユーザー・クラス・パスに追加します。 この例では-classpathオプションを使用します。
C:\>javac -classpath \examples \examples\greetings\Hi.java
greetings.Hiを変更してバナー・ユーティリティを使用するようにした場合、このユーティリティもユーザー・クラス・パスを通じてアクセスできる必要があります。
C:\>javac -classpath \examples;\lib\Banners.jar ^
\examples\greetings\Hi.java
greetingsパッケージのクラスを実行するには、プログラムがgreetingsパッケージおよびgreetingsクラスが使用するクラスにアクセスする必要があります。
C:\>java -classpath \examples;\lib\Banners.jar greetings.Hi
次の例では、javacを使用して、JVM 1.7上で動作するコードをコンパイルします。
javac -source 1.7 -target 1.7 -bootclasspath jdk1.7.0/lib/rt.jar \ -extdirs "" OldCode.java
-source 1.7オプションにより、OldCode.javaのコンパイルにはリリース1.7(または7)のJavaプログラミング言語が使用されます。 -target 1.7オプションにより、JVM 1.7と互換性のあるクラス・ファイルが生成されます。 ほとんどの場合、-targetオプションの値は-sourceオプションの値になります。この例では、-targetオプションを省略できます。
-bootclasspathオプションを使用して、正しいバージョンのブートストラップ・クラス(rt.jarライブラリ)を指定する必要があります。 指定しなかった場合は、コンパイラによって次の警告が生成されます。
javac -source 1.7 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.7
適切なバージョンのブートストラップ・クラスを指定しない場合、コンパイラは古い言語仕様(この例では、バージョン1.7のJavaプログラミング言語)を新しいブートストラップ・クラスと組み合せて使用します。その結果、存在しないメソッドへの参照が含まれていることがあるため、クラス・ファイルが古いプラットフォーム(この場合はJava SE 7)で動作しない可能性があります。
この例では、javacを使用して、JVM 1.7上で動作するコードをコンパイルします。
javac -source 1.7 -target 1.7 -bootclasspath C:\jdk1.7.0\lib\rt.jar ^
-extdirs "" OldCode.java
-source 1.7オプションにより、OldCode.javaのコンパイルにはリリース1.7(または7)のJavaプログラミング言語が使用されます。 -target 1.7オプションにより、JVM 1.7と互換性のあるクラス・ファイルが生成されます。
-bootclasspathオプションを使用して、正しいバージョンのブートストラップ・クラス(rt.jarライブラリ)を指定する必要があります。 指定しなかった場合は、コンパイラによって次の警告が生成されます。
javac -source 1.7 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.7
正しいバージョンのブートストラップ・クラスを指定しない場合、コンパイラは新しいブートストラップ・クラスと組み合わせて古い言語規則を使用します。 この組合わせにより、存在しないメソッドへの参照が含まれる可能性があるため、クラス・ファイルが古いプラットフォーム(この例ではJava SE 7)で動作しなくなることがあります。 この例で、コンパイラはリリース1.7のJavaプログラミング言語を使用します。