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プログラミング言語を使用します。