javac(1)

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

    o   形式

    o   説明

    o   オプション

    o   コマンドライン引数ファイル

    o   注釈処理

    o   型の検索

    o   プログラマティック・インタフェース

    o   例

    o   関連項目

形式

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

引数は順不同です。

    options
        コマンドライン・オプション。

    sourcefiles
        コンパイルされる1つ以上のソース・ファイル(MyClass.javaなど)。

    classes
        注釈の処理対象となる1つ以上のクラス(MyPackage.MyClassなど)。

    @argfiles
        オプションとソース・ファイルを列挙した1つ以上のファイル。このファイルの中では-Jオプションは指定できません。

説明

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

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

    o   ソース・ファイルの数が少ない場合は、ファイル名をコマンドラインで直接指定します。

    o   ソース・ファイルの数が多い場合は、ファイル名を空白または改行で区切って、1つのファイルに列挙します。次に、このリスト・ファイル名の先頭に@を付けて、javacのコマンドラインで指定します。

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

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

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

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

オプション

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

  標準オプション

    -Akey[=value]
        注釈プロセッサに渡されるオプション。これらは、javacによって直接解釈されず、個々のプロセッサによって使用されます。keyには、1つまたは複数の識別子を「.」で区切ったものを指定してください。

    -cppathまたは-classpathpath
        ユーザーのクラス・ファイルおよび(場合によっては)注釈プロセッサやソース・ファイルの検索場所を指定します。このクラス・パスはCLASSPATH環境変数のユーザー・クラス・パスをオーバーライドします。CLASSPATH、-cp、-classpathのいずれも指定されていない場合、ユーザー・クラス・パスは、現在のディレクトリになります。詳細は、クラス・パスの設定を参照してください。
        -sourcepathオプションが指定されていない場合は、ソース・ファイルもユーザー・クラス・パスから検索されます。
        -processorpathオプションが指定されていない場合は、注釈プロセッサもユーザー・クラス・パスから検索されます。

    -Djava.ext.dirs=directories
        インストール済拡張機能の位置をオーバーライドします。

    -Djava.endorsed.dirs=directories
        承認された標準パスの位置をオーバーライドします。

    -d directory
        クラス・ファイルの出力先ディレクトリを設定します。そのディレクトリはすでに存在している必要があります。javacでは作成されません。クラスがパッケージの一部である場合、javacは、必要に応じてディレクトリを作成し、パッケージ名を反映したサブディレクトリにクラス・ファイルを格納します。たとえば、-d/home/myclassesと指定し、クラスの名前がcom.mypackage.MyClassである場合、クラス・ファイルは/home/myclasses/com/mypackage/MyClass.classになります。
        -dが指定されなかった場合、javacは各クラス・ファイルを、その生成元となるソース・ファイルと同じディレクトリ内に格納します。
        注意: -dで指定したディレクトリはユーザー・クラス・パスに自動的には追加されません。

    -deprecation
        推奨されないメンバーやクラスが、使用またはオーバーライドされるたびに説明を表示します。-deprecationが指定されていない場合、javacは、推奨されないメンバーやクラスを使用またはオーバーライドしているソース・ファイルの要約を表示します。-deprecationは-Xlint:deprecationの省略表記です。

    -encoding encoding
        ソース・ファイルのエンコーディング名(EUC-JPや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起動ツールに、optionを渡します。たとえば、-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/home/mysrcと指定し、クラスの名前がcom.mypackage.MyClassであった場合、そのソース・ファイルは/home/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.1、1.2、1.3、1.4、1.5(5も可)、1.6(6も可)および1.7(7も可)です。

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

        o   -sourceが指定されなかった場合、-targetの値は1.7になります。

        o   -sourceが1.2の場合、-targetの値は1.4になります。

        o   -sourceが1.3の場合、-targetの値は1.4になります。

        o   -sourceが1.5の場合、-targetの値は1.7になります。

        o   -sourceが1.6の場合、-targetの値は1.7になります。

        o   -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}
        パッケージ情報ファイルの処理を指定します。

    -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 '...'
        コンパイラは、varargsメソッドを検出すると、varargsの仮パラメータを配列に変換します。メソッドClassWithVarargsMethod.varargsMethodでは、コンパイラはvarargsの仮パラメータString... sを仮パラメータString[] sに変換します。String[] sは、メソッドClassWithOverridingMethod.varargsMethodの仮パラメータに対応する配列です。その結果、この例ではコンパイルが行われます。

    path
        コマンドラインでの無効なパス要素と存在しないパス・ディレクトリについて警告します(クラス・パス、ソース・パスなどのパス関連)。このような警告を@SuppressWarnings注釈で抑制することはできません。次に例を示します。

        javac -Xlint:path -classpath /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に対して実行します。

        % 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に変更します。

    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によって参照されるListがlsに代入されると、コンパイラは未検査警告を生成します。コンパイラはlがList<String>型を参照するかどうかをコンパイル時に判断できません。また、JVMが実行時にそれを判断できないことも認識しています。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
        可変引数(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[] elementsに変換します。その結果、ヒープ汚染が発生する可能性があります。

コマンドライン引数ファイル

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

引数ファイルには、javacのオプションとソース・ファイル名を自由に組み合せて記述できます。ファイル内の各引数は、スペースまたは改行で区切ります。ファイル名に空白が含まれている場合は、そのファイル名全体を二重引用符で囲みます。

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

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

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

「argfile」という名前の引数ファイルにすべてのjavac引数を格納する場合は、次のように指定します。

% javac @argfile

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

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

たとえば、javacオプション用に1ファイル、ソース・ファイル名用に1ファイルというように、2つの引数ファイルを作成することもできます。なお、この後のリストでは、行の継続文字を使用していません。

次の内容を含む、「options」という名前のファイルを作成します。

     -d classes
     -g
     -sourcepath /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オプションを使用してプロセッサを明示的に指定することもできます。

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

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

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

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

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

型の検索

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

たとえば、java.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();
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のサブパッケージとして知られる)に含まれるその他のクラスやメソッドは、どれも完全に内部用であり、いつでも変更される可能性があります。

例

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

Hello.javaというソース・ファイルで、greetings.Helloという名前のクラスを定義しているとします。greetingsディレクトリは、ソース・ファイルとクラス・ファイルの両方があるパッケージ・ディレクトリで、現在のディレクトリのすぐ下にあります。このため、この例では、デフォルトのユーザー・クラス・パスを使用できます。また、-dを使用して別の出力先ディレクトリを指定する必要もありません。

% ls
greetings/
% ls greetings
Hello.java
% cat greetings/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]);
        }
    }
}
% javac greetings/Hello.java
% ls greetings
Hello.class   Hello.java
% java greetings.Hello World Universe Everyone
Hello World
Hello Universe
Hello Everyone

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

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

% ls
greetings/
% ls greetings
Aloha.java         GutenTag.java      Hello.java         Hi.java
% javac greetings/*.java
% ls greetings
Aloha.class         GutenTag.class      Hello.class         Hi.class
Aloha.java          GutenTag.java       Hello.java          Hi.java

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

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

% pwd
/examples
% javac greetings/Hi.java

greetings.Hiは、greetingsパッケージ内の他のクラスを参照しているため、コンパイラはこれらのクラスを探す必要があります。上の例では、デフォルトのユーザー・クラス・パスが、パッケージ・ディレクトリを含むディレクトリと同じであるため、コンパイルは正常に実行されます。しかし、現在どのディレクトリにいるかに関係なく、このファイルを再コンパイルする場合を考えてみましょう。そのような場合は、ユーザー・クラス・パスに/examplesを追加する必要があります。ユーザー・クラス・パスにエントリを追加するには、CLASSPATHを設定する方法もありますが、ここでは-classpathオプションを使用します。

% javac -classpath /examples /examples/greetings/Hi.java

再度greetings.Hiを変更してバナー・ユーティリティを使用するようにした場合は、このバナー・ユーティリティもユーザー・クラス・パスを通じてアクセスできるようになっている必要があります。

% javac -classpath /examples:/lib/Banners.jar \
            /examples/greetings/Hi.java

greetings内のクラスを実行するには、greetingsと、それが使用するクラスの両方にアクセスできる必要があります。

% java -classpath /examples:/lib/Banners.jar greetings.Hi

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

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

% ls
classes/  lib/      src/
% ls src
farewells/
% ls src/farewells
Base.java      GoodBye.java
% ls lib
Banners.jar
% ls classes
% javac -sourcepath src -classpath classes:lib/Banners.jar \
            src/farewells/GoodBye.java -d classes
% ls classes
farewells/
% ls classes/farewells
Base.class      GoodBye.class

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

  クロスコンパイルの例

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

% javac -source 1.6 -target 1.6 -bootclasspath 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ライブラリ)を指定する必要があります。指定しない場合は、コンパイラによって次の警告が生成されます。

% 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)で動作しない可能性があります。

関連項目

    o   javacガイド @
        http://docs.oracle.com/javase/7/docs/technotes/guides/javac/index.html

    o   java(1) - Javaアプリケーション起動ツール

    o   jdb(1) - Javaデバッガ

    o   javah(1) - Cヘッダーとスタブ・ファイル・ジェネレータ

    o   javap(1) - クラス・ファイル逆アセンブラ

    o   javadoc(1) - APIドキュメント・ジェネレータ

    o   jar(1) - JARアーカイブ・ツール

    o   Java拡張機能フレームワーク @
        http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/index.html