javac - Java プログラミング言語コンパイラ

形式

        javac [ options ] [ sourcefiles ] [ classes ] [ @argfiles ]

引数は順不同です。

options
コマンド行オプション。
sourcefiles
コンパイルされる 1 つ以上のソースファイル (MyClass.java など)。
classes
注釈の処理対象となる 1 つ以上のクラス (MyPackage.MyClass など)。
@argfiles
オプションとソースファイルを列挙した 1 つ以上のファイル。このファイルの中では、-J オプションは指定できません。

説明

javac ツールは、Java プログラミング言語で記述されたクラスとインタフェースの定義を読み取り、バイトコードのクラスファイルにコンパイルします。また、Java ソースファイルおよびクラス内の注釈の処理も行います。

ソースコードのファイル名を javac に渡すには、次の 2 つの方法があります。

ソースコードのファイル名は .java 拡張子を、クラスのファイル名は .class 拡張子を持っていなければなりません。また、ソースファイルとクラスファイルのどちらも、該当するクラスに対応するルート名を持っていなければなりません。たとえば、MyClass という名前のクラスは、MyClass.java という名前のソースファイルに記述します。このソースファイルは、MyClass.class という名前のバイトコードクラスファイルにコンパイルされます。

内部クラスが定義されていると、追加のクラスファイルが生成されます。これらのクラスファイルの名前は、MyClass$MyInnerClass.class のように、外部クラス名と内部クラス名を組み合わせたものになります。

ソースファイルは、パッケージツリーを反映したディレクトリツリーに配置する必要があります。たとえば、すべてのソースファイルを C:\workspace に置いている場合、com.mysoft.mypack.MyClass のソースコードは C:\workspace\com\mysoft\mypack\MyClass.java にある必要があります。

デフォルトでは、コンパイラは、各クラスファイルを対応するソースファイルと同じディレクトリに置きます。別の出力先ディレクトリを指定するには、-d を使用します (このあとの「オプション」を参照)。

オプション

コンパイラには、現在の開発環境でサポートされており、将来のリリースでもサポートされる標準オプションのセットがあります。これ以外の非標準オプションは、現在の仮想マシンおよびコンパイラの実装に固有のオプションで、将来に変更される可能性があります。非標準オプションは、-X で始まります。

標準オプション

-Akey[=value]
注釈プロセッサに渡されるオプション。これらは、javac によって直接解釈されず、個々のプロセッサによって使用されます。key には、1 つ以上の識別子を「.」で区切ったものを指定してください。
-cp path または -classpath path
ユーザーのクラスファイルおよび (場合によっては) 注釈プロセッサやソースファイルの検索場所を指定します。このクラスパスは CLASSPATH 環境変数のユーザークラスパスをオーバーライドします。CLASSPATH-cp-classpath のいずれも指定されていない場合、ユーザークラスパスは、現在のディレクトリになります。詳細は、「クラスパスの設定」を参照してください。

-sourcepath オプションが指定されていない場合は、ソースファイルもユーザークラスパスから検索されます。

-processorpath オプションが指定されていない場合は、注釈プロセッサもユーザークラスパスから検索されます。

-Djava.ext.dirs=directories
インストール型拡張機能の位置をオーバーライドします。
-Djava.endorsed.dirs=directories
承認された標準パスの位置をオーバーライドします。
-d directory
クラスファイルの出力先ディレクトリを設定します。そのディレクトリはすでに存在している必要があります。javac は作成しません。クラスがパッケージの一部である場合、javac は、必要に応じてディレクトリを作成し、パッケージ名を反映したサブディレクトリにクラスファイルを置きます。たとえば、-d C:\myclasses と指定した場合、クラスの名前が com.mypackage.MyClass であると、クラスファイルは C:\myclasses\com\mypackage\MyClass.class になります。

-d が指定されなかった場合、javac は各クラスファイルを、その生成元となるソースファイルと同じディレクトリ内に格納します。

注:-d で指定したディレクトリはユーザークラスパスに自動的には追加されません。

-deprecation
推奨されないメンバーやクラスが、使用またはオーバーライドされるたびに説明を表示します。-deprecation が指定されていない場合、javac は、推奨されないメンバーやクラスを使用またはオーバーライドしているソースファイルの要約を表示します。-deprecation-Xlint:deprecation の省略表記です。
-encoding encoding
ソースファイルのエンコーディング名 (EUC-JP and UTF-8 など) を指定します。-encoding が指定されていない場合は、プラットフォームのデフォルトコンバータが使われます。
-endorseddirs directories
承認された標準パスの位置をオーバーライドします。
-extdirs directories
ext ディレクトリの位置をオーバーライドします。directories 変数は、コロンで区切ったディレクトリのリストです。指定したディレクトリ内の各 JAR アーカイブから、クラスファイルが検索されます。見つかったすべての JAR アーカイブが自動的にクラスパスの一部になります。

クロスコンパイル (異なる Java プラットフォームに実装されたブートストラップクラスおよび拡張機能クラスに対するコンパイル) を行う場合、このオプションには拡張クラスが格納されているディレクトリを指定します。詳細は、「クロスコンパイルオプション」を参照してください。

-g
局所変数を含むすべてのデバッグ情報を生成します。デフォルトでは、行番号およびソースファイル情報だけが生成されます。
-g:none
デバッグ情報を生成しません。
-g:{keyword list}
コンマで区切られたキーワードリストにより指定された、特定の種類のデバッグ情報だけを生成します。次のキーワードが有効です。
source
ソースファイルのデバッグ情報
lines
行番号のデバッグ情報
vars
局所変数のデバッグ情報
-help
標準オプションの形式を表示します。
-implicit:{class,none}
暗黙的にロードされたソースファイルに対するクラスファイルの生成を制御します。クラスファイルを自動生成するには、-implicit:class を使用します。クラスファイルの生成を抑制するには、-implicit:none を使用します。このオプションが指定されなかった場合のデフォルト動作は、クラスファイルの自動生成になります。その場合、そのようなクラスファイルが生成されたときに注釈処理も実行されると、コンパイラから警告が発行されます。このオプションが明示的に設定された場合には、警告は発行されません。「型の検索」を参照してください。
-Joption
javac によって呼び出される java 起動ツールにオプションを渡します。たとえば、-J-Xms48m と指定すると、スタートアップメモリーは 48M バイトに設定されます。-J を使って、Java で記述されたベースとなる VM 実行アプリケーションにオプションを渡すことは、よく行われています。

注: CLASSPATH-classpath-bootclasspath、および -extdirs は、javac を実行するために使うクラスを指定するものではありません。このような方法でコンパイラの実装を操作することは、通常は無意味であり、常に危険を伴います。このような方法を使う必要がある場合は、-J オプションを使って、必要なオプションを背後の java 起動ツールに渡してください。

-nowarn
警告メッセージを無効にします。これは -Xlint:none と同じ意味です。
-proc: {none,only}
注釈処理、コンパイル、その両方、のいずれを実行するかを制御します。-proc:none は、注釈処理なしでコンパイルが実行されることを意味します。-proc:only は、注釈処理だけが実行され、後続のコンパイルはまったく実行されないことを意味します。
-processor class1[,class2,class3...]
実行する注釈プロセッサの名前。これを指定した場合、デフォルトの検索処理は省略されます。
-processorpath path
注釈プロセッサの検索場所を指定します。このオプションを使用しなかった場合、クラスパス内でプロセッサの検索が行われます。
-s dir
生成されたソースファイルの格納先となるディレクトリを指定します。そのディレクトリはすでに存在している必要があります。javac は作成しません。クラスがパッケージの一部になっていた場合、コンパイラはそのソースファイルを、パッケージ名を反映したサブディレクトリ内に格納します。その際、必要に応じてディレクトリを作成します。たとえば、ユーザーが -s C:\mysrc と指定し、クラスの名前が com.mypackage.MyClass であった場合、そのソースファイルは C:\mysrc\com\mypackage\MyClass.java 内に格納されます。
-source release
受け付けるソースコードのバージョンを指定します。release には次の値を指定できます。
1.3
このコンパイラでは、Java SE 1.3 以降に導入されたアサーション、ジェネリクス、またはその他の言語機能をサポートしません
1.4
Java SE 1.4 で導入された、アサーションを含むコードを受け付けます。
1.5
Java SE 5 で導入されたジェネリクスおよびその他の言語機能を含むコードを受け付けます。
5
1.5 と同義です。
1.6
Java SE 6 では言語に対する変更は導入されませんでしたが、ソースファイル内のエンコーディングエラーが、Java SE の以前のリリースのような「警告」ではなく、「エラー」として報告されるようになりました。
6
1.6 と同義です。
1.7
これがデフォルト値です。Java SE 7 で導入された機能を含むコードを受け付けます。
7
1.7 と同義です。
-sourcepath sourcepath
クラスまたはインタフェースの定義を検索するソースコードパスを指定します。ユーザークラスパスと同様に、ソースパスの複数のエントリはセミコロン (;) で区切ります。ソースパスのエントリには、ディレクトリ、JAR アーカイブ、または ZIP アーカイブを指定できます。パッケージを使っている場合は、ディレクトリまたはアーカイブ内のローカルパス名がパッケージ名を反映していなければなりません。

注:クラスパスからクラスだけでなくそのソースも見つかった場合、そのクラスは自動再コンパイルの対象になることがあります。「型の検索」を参照してください。

-verbose
詳細な出力を表示します。ロードされるクラスおよびコンパイルされるソースファイルごとの情報が出力されます。
-version
バージョン情報を出力します。
-Werror
警告が発生したらコンパイルを終了します。
-X
非標準オプションに関する情報を表示して終了します。

クロスコンパイルオプション

デフォルトでは、クラスのコンパイルは、javac が添付されているプラットフォームのブートストラップクラスおよび拡張機能クラスに対して行われます。ただし、javac は、異なる Java プラットフォームに実装されたブートストラップクラスおよび拡張機能クラスに対してコンパイルを行うクロスコンパイルもサポートしています。クロスコンパイルを行う場合は、-bootclasspath および -extdirs を使うことが重要です。このあとの「クロスコンパイルの例」を参照してください。

-target version
指定されたバージョンの VM をターゲットにしたクラスファイルを生成します。このクラスファイルは、指定されたターゲット以降のバージョンでは動作しますが、それより前のバージョンの VM では動作しません。有効なターゲットは、1.11.21.31.41.5 (5 も可)、1.6 (6 も可)、および 1.7 (7 も可) です。

-target のデフォルトは、次のように -source の値によって決まります。

  • -source が指定されなかった場合、-target の値は 1.7 になります。
  • -source が 1.2 の場合、-target の値は 1.4 になります。
  • -source が 1.3 の場合、-target の値は 1.4 になります。
  • -source が 1.5 の場合、-target の値は 1.7 になります。
  • -source が 1.6 の場合、-target の値は 1.7 になります。
  • -source がそれ以外の値の場合はすべて-target の値は -source の値になります。
-bootclasspath bootclasspath
指定された一連のブートクラスに対してクロスコンパイルを行います。ユーザークラスパスと同様に、ブートクラスパスの複数のエントリはコロン (:) で区切ります。ブートクラスパスのエントリには、ディレクトリ、JAR アーカイブ、または ZIP アーカイブを指定できます。

非標準オプション

-Xbootclasspath/p:path
ブートストラップクラスパスの前に追加します。
-Xbootclasspath/a:path
ブートストラップクラスパスの後ろに追加します。
-Xbootclasspath/:path
ブートストラップクラスファイルの位置をオーバーライドします。
-Xlint
推奨されるすべての警告を有効にします。このリリースでは、利用可能なすべての警告を有効にすることが推奨されています。
-Xlint:all
推奨されるすべての警告を有効にします。このリリースでは、利用可能なすべての警告を有効にすることが推奨されています。
-Xlint:none
すべての警告を無効にします。
-Xlint:name
警告 name を有効にします。このオプションで有効にできる警告のリストについては、「-Xlint オプションを使用して有効または無効にできる警告」を参照してください。
-Xlint:-name
警告 name を無効にします。このオプションで無効にできる警告のリストについては、「-Xlint オプションを使用して有効または無効にできる警告」を参照してください。
-Xmaxerrs number
印刷するエラーの最大数を設定します。
-Xmaxwarns number
印刷する警告の最大数を設定します。
-Xstdout filename
コンパイラのメッセージを、指定されたファイルに送ります。デフォルトでは、コンパイラのメッセージは System.err に送られます。
-Xprefer:{newer,source}
ある型に対してソースファイルとクラスファイルの両方が見つかった場合、そのどちらのファイルを読み取るべきかを指定します。(「型の検索」を参照)。-Xprefer:newer を使用した場合、ある型に対するソースファイルとクラスファイルの新しい方が読み取られます (デフォルト)。-Xprefer:source オプションを使用した場合、ソースファイルが読み取られます。SOURCE の保存ポリシーを使って宣言された注釈に任意の注釈プロセッサがアクセスできるようにしたい場合は、-Xprefer:source を使用してください。
-Xpkginfo:{always,legacy,nonempty}
package-info ファイルの処理を指定します。
-Xprint
指定された型のテキスト表現をデバッグ目的で出力します。注釈処理、コンパイルのどちらも実行しません。出力形式は変更される可能性があります。
-XprintProcessorInfo
ある特定のプロセッサが処理を依頼されている注釈に関する情報を出力します。
-XprintRounds
初回および後続の注釈処理ラウンドに関する情報を出力します。

-Xlint オプションを使用して有効または無効にできる警告

-Xlint:name オプションを使って警告 name を有効にします。name は次のいずれかの警告名です。同様に、-Xlint:-name オプションを使って警告 name を無効にできます。

cast
不要で冗長なキャストについて警告します。たとえば、
String s = (String)"Hello!"
classfile
クラスファイルの内容に関する問題について警告します。
deprecation
非推奨項目の使用について警告します。たとえば、
    java.util.Date myDate = new java.util.Date();
    int currentDay = myDate.getDay();

メソッド java.util.Date.getDay は、JDK 1.1 以降は推奨されていません。

dep-ann
@deprecated Javadoc コメントでドキュメント化されているが、@Deprecated 注釈が付いていない項目について警告します。たとえば、
  /**
   * @deprecated As of Java SE 7, replaced by {@link #newMethod()}
   */

  public static void deprecatedMethood() { }

  public static void newMethod() { }
divzero
定整数 0 による除算について警告します。次に例を示します。
    int divideByZero = 42 / 0;
empty
if 文のあとが空の文であることを警告します。たとえば、
class E {
    void m() {
        if (true) ;
    }
}
fallthrough
fall-through ケースの switch ブロックをチェックし、検出されたものに対して警告メッセージを表示します。Fall-through ケースは、switch ブロック内の最後のケースを除くケースです。このコードには break 文は含まれません。コードの実行をそのケースから次のケースへ移動します。たとえば、この switch ブロック内の case 1 ラベルに続くコードは、break 文で終わっていません。
switch (x) {
case 1:
       System.out.println("1");
       //  No break statement here.
case 2:
       System.out.println("2");
}

このコードのコンパイル時に -Xlint:fallthrough フラグが使用されていた場合、コンパイラは該当するケースの行番号とともに、fall-through ケースの可能性があることを示す警告を発行します。

finally
正常に完了できない finally 節について警告します。たとえば、
  public static int m() {
    try {
      throw new NullPointerException();
    } catch (NullPointerException e) {
      System.err.println("Caught NullPointerException.");
      return 1;
    } finally {
      return 0;
    }
  }

この例では、コンパイラは finally ブロックに関する警告を生成します。このメソッドが呼び出されると、値 1 ではなく 0 が返されます。finally ブロックは、try ブロックが終了すると必ず実行されます。この例では、catch に制御が移されると、メソッドは終了します。ただし、finally ブロックは実行される必要があるため、制御がすでにこのメソッドの外部に移されていても、このブロックは実行されます。

options
コマンド行オプションの使用に関する問題について警告します。この種の警告の例については、「クロスコンパイルの例」を参照してください。
overrides
メソッドのオーバーライドに関する問題について警告します。たとえば、次の 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 '...'

コンパイラが可変引数メソッド検出すると、可変引数仮パラメータを配列に変換します。メソッド ClassWithVarargsMethod.varargsMethod では、コンパイラは varargs の仮パラメータ String... s を仮パラメータ String[] s に (配列) 変換しますが、この配列はメソッド ClassWithOverridingMethod.varargsMethod の仮パラメータと一致します。その結果、この例ではコンパイルが行われます。

path
コマンド行のクラスパス、ソースパス、およびその他のパスとして指定された無効なパス要素と存在しないパスディレクトリについて警告します。このような警告は、@SuppressWarnings 注釈では抑制できません。たとえば、
javac -Xlint:path -classpath C:\nonexistentpath Example.java
processing
注釈処理に関する問題について警告します。コンパイラがこの警告を生成するのは、注釈を含むクラスがあり、そのタイプの例外を処理できない注釈プロセッサを使用している場合です。簡単な注釈プロセッサの例を次に示します。

ソースファイル AnnoProc.java:

import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.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 に対してこの注釈プロセッサを実行します。

C:\>javac AnnoProc.java
C:\>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 に変更します。

rawtypes
raw 型に対する未検査操作について警告します。次の文では、rawtypes 警告が生成されます。
void countElements(List l) { ... }

次の場合は、rawtypes 警告が生成されません。

void countElements(List<?> l) { ... }

List は raw 型です。ただし、List<?> はアンバウンド形式のワイルドカードのパラメータ化された型です。List はパラメータ化されたインタフェースなので、必ずその型引数を指定するようにしてください。この例では、List の仮引数はアンバウンド形式のワイルドカード (?) を使用してその仮型パラメータとして指定されています。つまり、countElements メソッドは List インタフェースの任意のインスタンス化を受け入れることができます。

serial
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
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
try-with-resources 文を含む、try ブロックの使用に関する問題について警告します。たとえば、try 文で宣言されたリソース ac が使用されていないため、次の文に対して警告が生成されます。
try ( AutoCloseable ac = getResource() ) {
    // do nothing
}
unchecked
Java 言語仕様で指定されている未検査変換警告の詳細を示します。たとえば、
    List l = new ArrayList<Number>();
    List<String> ls = l;       // unchecked warning

型の消去中に、型 ArrayList<Number> および List<String> はそれぞれ ArrayList および List になります。

変数 ls はパラメータ化された型 List<String> を持ちます。l によって参照される Listls に代入されると、コンパイラは未検査警告を生成します。コンパイラは、lList<String> 型を参照するかどうか (実際には参照しない) をコンパイル時に判断できません。また、JVM が実行時にそれを判断できないこともわかっています。その結果、ヒープ汚染が発生します。

詳しく説明すると、ヒープ汚染状態が発生するのは、List オブジェクト l (その static 型は List<Number>) が別の List オブジェクト ls (異なる static 型 List<String> を持つ) に代入される場合です。しかし、コンパイラはこの代入をいまだに許可しています。この代入を許可する必要があるのは、ジェネリクスをサポートしない Java SE のバージョンとの下位互換性を確保するためです。型消去のために、List<Number>List<String>List になります。その結果、コンパイラはオブジェクト l (List という raw 型を持つ) をオブジェクト ls に代入することを許可します。

varargs
可変引数 (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

コンパイラが可変引数メソッド検出すると、可変引数仮パラメータを配列に変換します。しかし、Java プログラミング言語では、パラメータ化された型の配列の作成は許可されません。メソッド ArrayBuilder.addToList では、コンパイラは varargs の仮パラメータ T... elements を仮パラメータ T[] elements に (配列) 変換します。しかし、型消去のために、コンパイラは varargs の仮パラメータを Object[] elements に変換します。その結果、ヒープ汚染が発生する可能性があります。

コマンド行引数ファイル

javac のコマンド行を短くしたり簡潔にしたりするために、javac コマンドに対する引数 (-J オプションを除く) が入った 1 つ以上のファイルを指定できます。この方法を使うと、どのオペレーティングシステム上でも、任意の長さの javac コマンドを作成できます。

引数ファイルには、javac のオプションとソースファイル名を自由に組み合わせて記述できます。ファイル内の各引数は、スペースまたは改行で区切ります。ファイル名に埋め込みの空白が含まれている場合は、そのファイル名全体を二重引用符で囲み、バックスラッシュを二重にします ("My Files\\Stuff.java")。

引数ファイル内のファイル名は、現在のディレクトリから見た相対パスになります。引数ファイルの位置から見た相対パスではありません。これらのリストでは、ワイルドカード (*) (*.java と指定するなど) は使用できません。ファイルを再帰的に解釈するための「@」文字の使用はサポートされていません。-J オプションもサポートされていません (起動ツールには渡されますが、それが引数ファイルをサポートしていないため)。

javac を実行するときに、各引数ファイルのパスとファイル名の先頭に @ 文字を付けて渡します。javac は、@ 文字で始まる引数を見つけると、そのファイルの内容を展開して引数リストに挿入します。

引数ファイルを 1 つ指定する例

argfile という名前の引数ファイルにすべての Javac 引数を格納し、次のように使用できます。

C:\>javac @argfile

この引数ファイルには、次の例で示されている 2 つのファイルの内容を両方とも入れることができます。

引数ファイルを 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 を実行します。

C:\>javac @options @classes

パス付きの引数ファイルの例

引数ファイルにパスを指定できますが、ファイル内のファイル名は (path1path2 ではなく) 現在の作業ディレクトリへの相対です。

C:\>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 オプションを使ってプロセッサを明示的に指定することもできます。

コンパイラは、コマンド行のソースファイルやクラスを走査することで、どのような注釈が存在しているかを確認し終わると、プロセッサに対して問い合わせを行い、それらのプロセッサがどの注釈を処理できるのかを確認します。一致するものが見つかった場合、そのプロセッサが呼び出されます。各プロセッサは、自身が処理する注釈を「要求」できます。その場合、それらの注釈に対する別のプロセッサを見つける試みは行われません。すべての注釈が要求されてしまうと、コンパイラはそれ以上プロセッサの検索を行いません。

いずれかのプロセッサによって新しいソースファイルが生成されると、注釈処理の 2 回目のラウンドが開始されます。新しく生成されたすべてのソースファイルが走査され、前回と同様に注釈が処理されます。以前のラウンドで呼び出されたプロセッサはすべて、後続のどのラウンドでも呼び出されます。これが、新しいソースファイルが生成されなくなるまで続きます。

あるラウンドで新しいソースファイルが生成されなかった場合、注釈プロセッサがあと 1 回だけ呼び出され、必要な処理を実行する機会が与えられます。最後に、-proc:only オプションが使用されないかぎり、コンパイラは、元のソースファイルと生成されたすべてのソースファイルをコンパイルします。

暗黙的にロードされたソースファイル

コンパイラは、一連のソースファイルをコンパイルする際に、別のソースファイルを暗黙的にロードしなければならない場合があります。(「型の検索」を参照)。そのようなファイルは、現時点では注釈処理の対象になりません。デフォルトでは、注釈処理が実行され、かつ暗黙的にロードされたソースファイルが 1 つでもコンパイルされた場合にコンパイラは警告を発行します。この警告を抑制する方法については、-implicit オプションを参照してください。

型の検索

ソースファイルをコンパイルする場合、コマンド行で指定したソースファイルに型の定義が見つからないとき、コンパイラは通常、その型に関する情報を必要とします。コンパイラは、ソースファイルで使われているクラスまたはインタフェース、拡張されているクラスまたはインタフェース、あるいは実装されているクラスまたはインタフェースすべてについて、型の情報を必要とします。これには、ソースファイルで明示的には言及されていなくても、継承を通じて情報を提供するクラスとインタフェースも含まれます。

たとえば、java.applet.Applet をサブクラスにした場合、アプレットの祖先のクラス(java.awt.Paneljava.awt.Containerjava.awt.Componentjava.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();
int rc = javac.run(null, null, null, args);

この場合、標準出力ストリームにすべての診断メッセージが書き出され、コマンド行から呼び出された 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 パラメータは、javac プログラムに通常渡される任意のコマンド行引数を表しています。その概要については、前出の「形式」セクションを参照してください。

out パラメータは、コンパイラの診断メッセージの出力先を示します。

戻り値は、javac の終了値と同じです。

名前が com.sun.tools.javac で始まるパッケージ (非公式には com.sun.tools.javac のサブパッケージとして知られる) に含まれるその他のクラスやメソッドは、いずれも完全に内部用であり、いつでも変更される可能性があります。

簡単なプログラムのコンパイル

以下に示すソースファイル C:\greetings\Hello.java では、greetings.Hello という名前のクラスを定義しています。

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 ディレクトリは、ソースファイルとクラスファイルの両方があるパッケージディレクトリで、現在のディレクトリのすぐ下にあります。このため、この例では、デフォルトのユーザークラスパスを使用できます。また、-d を使って別の出力先ディレクトリを指定する必要もありません。

C:\>javac greetings\Hello.java
C:\>dir greetings /B
Hello.class
Hello.java
C:\>java greetings.Hello World Universe Everyone
Hello World
Hello Universe
Hello Everyone

複数のソースファイルのコンパイル

次の例では、パッケージ greetings 内のすべてのソースファイルをコンパイルします。

C:\>dir /B
greetings
C:\>dir greetings /B
Aloha.java
GutenTag.java
Hello.java
Hi.java
C:\>javac greetings\*.java
C:\>dir greetings /B
Aloha.class                        
Aloha.java                           
GutenTag.class
GutenTag.java
Hello.class
Hello.java
Hi.class
Hi.java

ユーザークラスパスの指定

上の例のソースファイルのうち 1 つを変更し、変更後のファイルを再コンパイルするとします。

C:\>cd
\examples
C:\>javac greetings\Hi.java

greetings.Hi は、greetings パッケージ内のほかのクラスを参照しているため、コンパイラはこれらのクラスを探す必要があります。上の例では、デフォルトのユーザークラスパスが、パッケージディレクトリを含むディレクトリと同じであるため、コンパイルは正常に実行されます。ただし、現在どのディレクトリにいるかに関係なく、このファイルを再コンパイルする場合は、ユーザークラスパスに \examples を追加する必要があります。ユーザークラスパスにエントリを追加するには、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

ソースファイルとクラスファイルの分離

特に大規模プロジェクトの場合は、ソースファイルとクラスファイルを別々のディレクトリに置くと便利なことがあります。クラスファイルの出力先を別に指定するには、-d を使います。ソースファイルはユーザークラスパスにはないので、-sourcepath を使って、コンパイラがソースファイルを見つけることができるようにします。

C:\>dir /B
classes
lib
src
C:\>dir src
farewells
C:\>dir src\farewells
Base.java
GoodBye.java
C:\>dir lib
Banners.jar
C:\>dir classes
C:\>javac -sourcepath src -classpath classes;lib\Banners.jar ^
            src\farewells\GoodBye.java -d classes
C:\>dir classes
farewells
C:\>dir classes\farewells
Base.class
GoodBye.class

注:コマンド行では src\farewells\Base.java を指定していませんが、このファイルもコンパイラによってコンパイルされています。自動コンパイルを監視するには、-verbose オプションを使います。

クロスコンパイルの例

次の例は、1.6 VM 上で動作するコードをコンパイルするために javac を使用します。

C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar ^
            -extdirs "" OldCode.java

-source 1.6 オプションを指定すると、OldCode.java のコンパイルにはバージョン 1.6 (または 6) の Java プログラミング言語が使用されます。-target 1.6 オプションを使用すると、1.6 VM と互換性のあるクラスファイルが生成されます。ほとんどの場合、-target オプションの値は -source オプションの値になります。この例では、-target オプションを省略できます。

-bootclasspath オプションを使用して、正しいバージョンのブートストラップクラス (rt.jar ライブラリ) を指定する必要があります。指定しなかった場合は、コンパイラによって次の警告が生成されます。

C:\>javac -source 1.6 OldCode.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6

正しいバージョンのブートストラップクラスを指定しなかった場合、コンパイラは古い言語規則 (この例では、バージョン 1.6 の Java プログラミング言語) を新しいブートストラップクラスと組み合わせて使用します。その結果、存在しないメソッドへの参照が含まれていることがあるため、クラスファイルが古いプラットフォーム (この場合は Java SE 6) で動作しない可能性があります。

関連項目


Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.