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

形式

javac [ options ] [ sourcefiles ] [ @files ]
oldjavac [ options ] [ sourcefiles ] [ @files ]
引数の順は任意です。
options
コマンド行オプション
sourcefiles
コンパイルされる 1 つ以上のソースファイル (MyClass.java など)
@files
ソースファイルを一覧表示する 1 つ以上のファイル

解説

javac ツールは、Java プログラミング言語で記述されたクラスとインタフェースの定義を読み取り、バイトコードクラスファイルにコンパイルします。

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

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

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

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

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

型の検索

ソースファイルをコンパイルするとき、コンパイラには、まだ認識していない型に関する情報が必要になることがあります。コンパイラには、ソースファイルで使われているクラスまたはインタフェース、拡張されているクラスまたはインタフェース、あるいは実装されているクラスまたはインタフェースそれぞれの型情報が必要です。これには、ソースファイルで明示的には言及されていなくても、継承を通じて情報を提供するクラスとインタフェースも含まれます。

たとえば、java.applet.Applet をサブクラス化する場合は、Applet の上位クラスである java.awt.Paneljava.awt.Containerjava.awt.Component、および java.awt.Object も使っています。

コンパイラは、型情報が必要になると、該当する型を定義しているソースファイルまたはクラスファイルを探します。コンパイラは、まず、ブートストラップクラスと拡張機能クラスを検索し、次にユーザクラスパスを検索します。ユーザクラスパスは、CLASSPATH 環境変数を設定するか、あるいは -classpath コマンド行オプションを使って設定します。詳細は、「クラスパスの設定」を参照してください。-sourcepath オプションが指定されている場合、コンパイラは、指定されたパスでソースファイルを検索します。 それ以外の場合は、ユーザクラスパスでクラスファイルとソースファイルの両方を検索します。 -bootclasspath オプションと -extdirs オプションを使うと、別のブートストラップクラスや拡張機能クラスを指定できます。後述の「クロスコンパイルオプション」を参照してください。

型の検索に成功したときに得られる結果は、クラスファイル、ソースファイル、またはその両方である場合があります。それぞれの場合に javac がどのように処理を行うかを次に示します。

javac は、コマンド行に指定されていないソースファイルをコンパイルするときでも、そのことを示すメッセージを表示しません。自動コンパイルをトレースするには、-verbose オプションを使ってください。

ファイルのリスト

javac コマンドを短く簡潔にするために、各行にファイル名が 1 つ記述されているファイルを 1 つまたは複数指定することができます。コマンド行で、ファイル名をファイルのリストとして指定するには、ファイル名とともに @ 文字を使います。javac は、「@」文字で始まる引数に遭遇すると、そのファイル内にあるファイル名がコマンド行に書かれていたかのように、それらのファイル名に対して操作を行います。

たとえば、sourcefiles というファイル内に、次のようにすべてのソースファイル名を列挙できます。リストファイルは、次のようになります。

     MyClass1.java
     MyClass2.java
     MyClass3.java    
次のコマンドを使って、コンパイラを実行できます。
     % javac @sourcefiles

オプション

コンパイラには、現在の開発環境でサポートされ、将来のリリースでもサポートされる標準オプションのセットがあります。このほかの非標準オプションは、現在の Virtual Machine とコンパイラの実装に固有のオプションで、将来変更される可能性があります。標準でないオプションは、-X で始まります。

標準オプション

-classpath classpath
ユーザクラスパスを設定し、CLASSPATH 環境変数のユーザクラスパスを上書きします。CLASSPATH-classpath のどちらも指定されていない場合、ユーザクラスパスは現在のディレクトリになります。詳細は、「クラスパスの設定」を参照してください。

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

-d directory
クラスファイルの出力先ディレクトリを設定します。クラスがパッケージの一部である場合、javac は、必要に応じてディレクトリを作成し、パッケージ名を反映したサブディレクトリにクラスファイルを置きます。たとえば、-d /home/myclasses と指定し、クラスの名前が com.mypackage.MyClass である場合、クラスファイルは /home/myclasses/com/mypackage/MyClass.class になります。

-d が指定されていない場合、javac はソースファイルと同じディレクトリにクラスファイルを置きます。

-d で指定されたディレクトリがユーザクラスパスに自動的に追加されるわけではないことに注意してください。

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

-encoding
ソースファイルのエンコーディング名 (EUCJIS/SJIS など) を指定します。-encoding が指定されていない場合は、プラットフォームのデフォルトコンバータが使われます。

-g
局所変数を含むすべてのデバッグ情報を生成します。デフォルトでは、行番号およびソースファイル情報だけが生成されます。

-g:none
デバッグ情報は生成されません。

-g:{keyword list}
コンマで区切られたキーワードリストにより指定された、特定の種類のデバッグ情報だけを生成します。次のキーワードが有効です。
source
ソースファイルのデバッグ情報
lines
行番号のデバッグ情報
vars
局所変数のデバッグ情報

-nowarn
警告メッセージを表示しません。

-O
注: -O オプションを指定しても、javac と oldjavac の現在の実装では処理は行われません。
実行時のコードを最適化します。-O オプションを指定すると、コンパイル速度が低下し、作成されるクラスファイルのサイズが増大して、デバッグの困難なプログラムが生成されることがあります。

Java 2 SDK v1.2 より前は、javac の -g オプションと -O オプションを一緒に使うことができませんでした。Java 2 SDK v1.2 では、これらのオプションを組み合わせることができますが、変数の喪失、コードの移動や喪失などの思わぬ結果になる可能性があります。-O オプションを指定しても、-depend オプションが自動的に有効になったり、-g オプションが自動的に無効になったりすることはなくなりました。

-sourcepath sourcepath
クラスまたはインタフェースの定義を検索するソースコードパスを指定します。ユーザクラスパス同様、ソースパスの複数のエントリはコロン (:) で区切ります。 ソースパスのエントリには、ディレクトリ、JAR アーカイブ、または ZIP アーカイブを指定できます。パッケージを使っている場合は、ディレクトリまたはアーカイブ内のローカルパス名がパッケージ名を反映していなければなりません。

ソースが見つかった場合、クラスパスで見つかったクラスは、自動再コンパイルの対象になります。

-verbose
冗長出力を指定します。ロードされるクラスおよびコンパイルされるソースファイルごとに情報を出力します。

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

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

-target version
指定されたバージョンの VM 上で動作するクラスファイルを生成します。デフォルトでは、1.1 VM と Java 2 SDK の VM の両方に互換性のあるクラスファイルを生成します。Java 2 SDK の javac がサポートするバージョンは次のとおりです。

1.1
生成するクラスファイルが、1.1 VM と Java 2 SDK の VM に互換性があることを保証します。これはデフォルトの動作です。
1.2
Java 2 SDK, v 1.2 以降の VM 上では動作するが、1.1 の VM 上では動作しないクラスファイルを生成します。
1.3
Java 2 SDK, v 1,3 以降の VM 上では動作するが、1.1 または 1.2 の VM 上では動作しないクラスファイルを生成します。

-bootclasspath bootclasspath
指定された一連のブートクラスに対してクロスコンパイルを行います。ユーザクラスパス同様、ブートクラスパスの複数のエントリはコロン (:) で区切ります。 ブートクラスパスのエントリには、ディレクトリ、JAR アーカイブ、または ZIP アーカイブを指定できます。

-extdirs directories
指定された拡張機能ディレクトリに対してクロスコンパイルを行います。directories には、コロンで区切ったディレクトリのリストを指定します。指定されたディレクトリ内の各 JAR アーカイブで、クラスファイルが検索されます。

非標準オプション

以下のオプションは、oldjavac だけでサポートされています。新しい javac コンパイラではサポートされていません。

-X
非標準オプションに関する情報を表示して終了します。

-Xdepend
アクセス可能なすべてのクラスを再帰的に検索し、再コンパイル用のより新しいソースファイルを探します。このオプションを使うと、再コンパイルの必要なクラスをより信頼性の高い方法で検索できますが、コンパイル処理時間が大幅に長くなる可能性があります。

-Xstdout
コンパイラのメッセージを System.out に送信します。デフォルトでは、コンパイラのメッセージは System.err に送信されます。

-Xverbosepath
ソースファイルおよびクラスファイルを見つけるために、パスおよび標準拡張機能を検索する方法を記述します。

-J オプション

-J オプションは、javac および oldjavac でサポートされています。
-Joption
javac が呼び出す java 起動コマンドに、option を渡します。たとえば、-J-Xms48m と指定すると、スタートアップメモリは 48M バイトに設定されます。このオプションは -X では始まりませんが、javac の「標準オプション」ではありません。オプションを Java で記述されたアプリケーションを実行している背後の VM に渡すことは、-J 共通の規則です。

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

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

次に示すソースファイル 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 と、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 オプションを使ってください。

クロスコンパイルの例

ここでは、Java 2 SDK の javac を使って 1.1 VM 上で実行するコードをコンパイルします。
% javac -target 1.1 -bootclasspath jdk1.1.7/lib/classes.zip \
             -extdirs "" OldCode.java
-target 1.1 オプションにより、生成されるクラスファイルが 1.1 VM との互換性を保持することが保証されます。Java 2 SDK の javac は、デフォルトで 1.1 への互換性を維持してコンパイルを行うので、このオプションは厳密には必要ありません。ただし、コンパイラによってデフォルトが異なる可能性があるので、このオプションを指定する習慣をつけておくとよいでしょう。

Java 2 SDK の javac は、デフォルトでは、Java 2 SDK のブートストラップクラスに対してコンパイルを行うので、Java 2 SDK ではなく JDK 1.1 のブートストラップクラスに対してコンパイルを行うように指定する必要があります。これは、-bootclasspath および -extdirs を使って行います。この指定を行わないと、1.1 VM には存在しない Java 2 プラットフォームの API に対応したコンパイルが行われるため、実行中に障害が発生する可能性があります。

関連項目