javac [ options ] [ sourcefiles ] [ classes] [ @argfiles ]
引数を指定する順序は任意です。
options
sourcefiles
classes
@argfiles
javacコマンドは、Javaプログラミング言語で記述されたクラスとインタフェースの定義を読み取り、バイトコードのクラス・ファイルにコンパイルします。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オプションを使用して、別の出力先ディレクトリを指定できます。
コンパイラには、現在の開発環境でサポートされる標準オプションのセットがあります。これ以外の非標準オプションは、現在の仮想マシンおよびコンパイラの実装に固有のオプションで、将来、変更される可能性があります。非標準オプションは、-Xオプションで始まります。
-Akey[=value]
-cp path or -classpath path
-sourcepathオプションが指定されていない場合、ソース・ファイルもユーザー・クラス・パスから検索されます。
-processorpathオプションが指定されていない場合、注釈プロセッサもクラス・パスから検索されます。
-Djava.ext.dirs=directories
-Djava.endorsed.dirs=directories
-d directory
-d /home/myclassesと指定し、クラスの名前がcom.mypackage.MyClassである場合、クラス・ファイルは/home/myclasses/com/mypackage/MyClass.classになります。
-dオプションが指定されなかった場合、javacは、各クラス・ファイルを、その生成元となるソース・ファイルと同じディレクトリ内に格納します。
注意: -dオプションによって指定されたディレクトリは、ユーザー・クラス・パスに自動的に追加されません。
-deprecation
-encoding encoding
-endorseddirs directories
-extdirs directories
クロスコンパイル(異なるJavaプラットフォームに実装されたブートストラップ・クラスや拡張機能クラスに対してコンパイルを行う)を実行する場合、このオプションには拡張機能クラスを含むディレクトリを指定します。詳細はクロスコンパイル・オプションを参照してください。
-g
-g:none
-g:[keyword list]
source
lines
vars
-help
-implicit:[class, none]
-Joption
注意: CLASSPATH、-classpath、-bootclasspathおよび-extdirsオプションは、javacの実行に使用されるクラスを指定しません。これらのオプションおよび変数を使用してコンパイラの実装をカスタマイズしようとすると、リスクが高く、多くの場合、必要な処理が実行されません。コンパイラの実装をカスタマイズする必要がある場合、-Jオプションを使用して、基礎となるJava起動ツールにオプションを渡します。
-nowarn
-parameters
-proc: [none, only]
-processor class1 [,class2,class3...]
-processorpath path
-s dir
-s /home/mysrcと指定し、クラスの名前がcom.mypackage.MyClassである場合、ソース・ファイルは/home/mysrc/com/mypackage/MyClass.javaに格納されます。
-source release
1.3
1.4
1.5
5
1.6
6
1.7
7
1.8
8
-sourcepath sourcepath
注意: ソース・ファイルも見つかった場合、クラス・パスにより見つかったクラスは再コンパイルされる可能性があります。型の検索を参照してください。
-verbose
-version
-werror
-X
デフォルトでは、クラスのコンパイルは、javacが添付されているプラットフォームのブートストラップ・クラスおよび拡張機能クラスに対して行われます。ただし、javacは、異なるJavaプラットフォームに実装されたブートストラップ・クラスおよび拡張機能クラスに対してコンパイルを行うクロスコンパイルもサポートしています。クロスコンパイルを行う場合は、-bootclasspathおよび-extdirsオプションを使用することが重要です。
-target version
-targetオプションのデフォルトは、-sourceオプションの値によって異なります。
-bootclasspath bootclasspath
JDK 8以降から、javacコンパイラはコンパクト・プロファイルをサポートします。コンパクト・プロファイルを使用すると、Javaプラットフォーム全体を必要としないアプリケーションは、デプロイ可能で、小さいフットプリントで実行できます。コンパクト・プロファイル機能は、アプリケーション・ストアからのアプリケーションのダウンロード時間を短縮するのに使用できます。この機能は、JREをバンドルするJavaアプリケーションの、よりコンパクトなデプロイメントに役立ちます。この機能は、小さいデバイスでも役立ちます。
サポートされているプロファイル値は、compact1、compact2およびcompact3です。これらは、追加のレイヤーです。大きい番号の各コンパクト・プロファイルには、小さい番号の名前のプロファイル内のすべてのAPIが含まれます。
-profile
javac -profile compact1 Hello.java
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;
コンパクト・プロファイルを使用してコンパイルするための別の方法として、-bootclasspathオプションを使用して、プロファイルのイメージを指定するrt.jarファイルへのパスを指定します。かわりに-profileオプションを使用すると、プロファイル・イメージは、コンパイル時にシステム上に存在する必要がありません。これは、クロスコンパイル時に役立ちます。
-Xbootclasspath/p:path
-Xbootclasspath/a:path
-Xbootclasspath/:path
-Xdoclint:[-]group [/access]
変数accessは、-Xdoclintオプションがチェックするクラスとメンバーの最小の可視性レベルを指定します。public、protected、packageおよびprivateの値(可視性の高い順)の1つを持つことができます。たとえば、次のオプションは、(protected、package、publicを含む) protected以上のアクセス・レベルを持つクラスおよびメンバーを(すべてのチェック・グループで)チェックします。
-Xdoclint:all/protected
-Xdoclint:all,-html/package
-Xdoclint:none
-Xdoclint:all[/access]
-Xlint
-Xlint:all
-Xlint:none
-Xlint:name
-Xlint:-name
-Xmaxerrs number
-Xmaxwarns number
-Xstdout filename
-Xprefer:[newer,source]
-Xpkginfo:[always,legacy,nonempty]
always
legacy
注意: package-info.classファイルは生成できますが、package-info.javaファイル内のすべての注釈にRetentionPolicy.SOURCEがある場合は空になります。
nonempty
-Xprint
-XprintProcessorInfo
-XprintRounds
-Xlint:nameオプションを使用して警告nameを有効にします。ここで、nameは次の警告名のいずれかになります。-Xlint:-name:オプションを使用して、警告を無効化できます。
cast
String s = (String) "Hello!"
classfile
deprecation
java.util.Date myDate = new java.util.Date(); int currentDay = myDate.getDay();
dep-ann
/** * @deprecated As of Java SE 7, replaced by {@link #newMethod()} */ public static void deprecatedMethood() { } public static void newMethod() { }
divzero
int divideByZero = 42 / 0;
empty
class E { void m() { if (true) ; } }
fallthrough
switch (x) { case 1: System.out.println("1"); // No break statement here. case 2: System.out.println("2"); }
finally
public static int m() { try { throw new NullPointerException(); } catch (NullPointerException(); { System.err.println("Caught NullPointerException."); return 1; } finally { return 0; } }
options
overrides
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 '...'
path
javac -Xlint:path -classpath /nonexistentpath Example.java
processing
ソース・ファイル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(); } }
@interface Anno { } @Anno class AnnosWithoutProcessors { }
javac AnnoProc.java javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java
warning: [processing] No processor claimed any of these annotations: Anno
rawtypes
void countElements(List l) { ... }
void countElements(List<?> l) { ... }
Serial
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
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
XLintStatic.m1();
try
try ( AutoCloseable ac = getResource() ) { // do nothing}
unchecked
List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning
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
javacコマンドを短くしたり簡潔にしたりするために、javacコマンドに対する引数(-Jオプションを除く)を含む1つ以上のファイルを指定することができます。これにより、どのオペレーティング・システム上でも、任意の長さのjavacコマンドを作成できます。
引数ファイルには、javacのオプションとソース・ファイル名を自由に組み合せて記述できます。ファイル内の引数は、空白または改行文字で区切ることができます。ファイル名に埋め込まれた空白がある場合、ファイル名全体を二重引用符で囲みます。
引数ファイル内のファイル名は、引数ファイルの位置ではなく、現在のディレクトリに相対的となります。これらのリストでは、ワイルドカード(*)は使用できません(たとえば、*.javaとは指定できません)。アットマーク(@)を使用したファイルの再帰的な解釈はサポートされていません。また、-Jオプションもサポートされていません。このオプションは起動ツールに渡されますが、起動ツールでは引数ファイルをサポートしていないからです。
javacコマンドを実行するときに、各引数ファイルのパスと名前の先頭にアットマーク(@)文字を付けて渡します。javacコマンドは、アットマーク(@)で始まる引数を見つけると、そのファイルの内容を展開して引数リストに挿入します。
例 1 単一の引数ファイル
javac @argfile
例 2 2つの引数ファイル
次を含むoptionsという名前のファイルを作成します。
-d classes
-g
-sourcepath /java/pubs/ws/1.3/src/share/classes
MyClass1.java MyClass2.java MyClass3.java
javac @options @classes
例 3 パスを使用した引数ファイル
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オプションが使用されないかぎり、コンパイラは、元のソース・ファイルと生成されたすべてのソース・ファイルをコンパイルします。
コンパイラは、一連のソース・ファイルをコンパイルする際に、別のソース・ファイルを暗黙的にロードすることが必要な場合があります。型の検索を参照してください。そのようなファイルは、現時点では注釈処理の対象になりません。デフォルトでは、注釈処理が実行され、かつ暗黙的にロードされた任意のソース・ファイルがコンパイルされた場合、コンパイラは警告を発行します。-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();
例では、診断を標準出力ストリームに書き込み、コマンド行からの呼出し時に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のサブパッケージ)で検出される他のすべてのクラスおよびメソッドは、完全に内部用であり、いつでも変更される可能性があります。
例 1 簡単なプログラムのコンパイル
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
java greetings.Hello World Universe Everyone Hello World Hello Universe Hello Everyone
例 2 複数のソース・ファイルのコンパイル
% javac greetings/*.java % ls greetings Aloha.class GutenTag.class Hello.class Hi.class Aloha.java GutenTag.java Hello.java Hi.java
例 3 ユーザー・クラス・パスの指定
pwd /examples javac greetings/Hi.java
javac -classpath /examples /examples/greetings/Hi.java
javac -classpath /examples:/lib/Banners.jar \ /examples/greetings/Hi.java
java -classpath /examples:/lib/Banners.jar greetings.Hi
例 4 ソース・ファイルとクラス・ファイルの分離
javac -source 1.7 -target 1.7 -bootclasspath jdk1.7.0/lib/rt.jar \ -extdirs "" OldCode.java
-bootclasspathオプションを使用して、適切なバージョンのブートストラップ・クラス(rt.jarライブラリ)を指定する必要があります。指定しない場合は、コンパイラによって次の警告が生成されます。
javac -source 1.7 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.7
例 5 クロス・コンパイル
javac -source 1.7 -target 1.7 -bootclasspath jdk1.7.0/lib/rt.jar \ -extdirs "" OldCode.java
-bootclasspathオプションを使用して、適切なバージョンのブートストラップ・クラス(rt.jarライブラリ)を指定する必要があります。指定しない場合は、コンパイラによって次の警告が生成されます。
javac -source 1.7 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.7