javac(1) 基本ツール javac(1)

# 名前

javac - Javaクラスおよびインタフェースの定義を読み取り、バイトコードおよびクラス・ファイルにコンパイルします。

# 概要

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

引数を指定する順序は任意です。

*options*

コマンド行オプション。オプションを参照してください。

*sourcefiles*

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

*classes*

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

*@argfiles*

オプションとソース・ファイルを一覧表示する1つ以上のファイル。このファイルの中では**-J**オプションは指定できません。コマンド行引数ファイルを参照してください。

# 説明

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

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

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

•ソース・ファイルの数が多い場合は、ファイル内のファイル名を空白または改行で区切って指定します。**javac**コマンドで、リスト・ファイル名の先頭にアットマーク(@)を使用します。

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

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

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

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

# オプション

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

•クロスコンパイル・オプションも参照してください

•非標準オプションも参照してください

## 標準オプション

-A*key*\[*=value*]

注釈プロセッサに渡すオプションを指定します。これらのオプションは、**javac**が直接解釈するのではなく、それぞれのプロセッサで使用できるようになります。**key**の値は、1つまたは複数の識別子をドット(.)で区切る必要があります。

-cp *path* or -classpath *path*

ユーザー・クラス・ファイル、および(オプションで)注釈プロセッサとソース・ファイルを検索する場所を指定します。このクラス・パスは**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**を使用します。このオプションが指定されなかった場合のデフォルト動作は、クラス・ファイルの自動生成になります。その場合、そのようなクラス・ファイルが生成された時に注釈処理も実行されると、コンパイラから警告が発行されます。**-implicit**オプションが明示的に設定された場合、警告は発行されません。型の検索を参照してください。

-J*option*

Java Virtual Machine (JVM)に**option**を渡します。optionには、Java起動ツールのリファレンス・ページに記載されているオプションを1つ指定します。たとえば、**-J-Xms48m**と指定すると、スタートアップ・メモリーは48MBに設定されます。[java(1)](/man/os/openjdk-11/java.1)を参照してください。

**注意:** *CLASSPATH*、**-classpath**、**-bootclasspath**および**-extdirs**オプションは、**javac**の実行に使用されるクラスを指定しません。これらのオプションおよび変数を使用してコンパイラの実装をカスタマイズしようとすると、リスクが高く、多くの場合、必要な処理が実行されません。コンパイラの実装をカスタマイズする必要がある場合、**-J**オプションを使用して、基礎となるJava起動ツールにオプションを渡します。

-nowarn

警告メッセージを無効にします。このオプションは、**-Xlint:none**オプションと同じように動作します。

-parameters

リフレクションAPIのメソッド**java.lang.reflect.Executable.getParameters**が取得できるように、生成されるクラス・ファイル内のコンストラクタとメソッドの仮パラメータ名を格納します。

-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 Platform, Standard Editionの以前のリリースような警告ではなく、エラーとして報告されるようになりました。

6

1.6と同義です。

1.7

Java SE 7で導入された機能を含むコードを受け付けます。

7

1.7と同義です。

1.8

これがデフォルト値です。Java SE 8で導入された機能を含むコードを受け付けます。

8

1.8と同義です。

-sourcepath *sourcepath*

クラスまたはインタフェースの定義を検索するソース・コード・パスを指定します。ユーザー・クラス・パスと同様に、ソース・パスのエントリは、Oracle Solarisではコロン(:)で、Windowsではセミコロンで区切り、ここには、ディレクトリ、JARアーカイブまたはZIPアーカイブを指定できます。パッケージを使用している場合は、ディレクトリまたはアーカイブ内のローカル・パス名がパッケージ名を反映している必要があります。

**注意:** ソース・ファイルも見つかった場合、クラス・パスにより見つかったクラスは再コンパイルされる可能性があります。型の検索を参照してください。

-verbose

ロードされるクラスおよびコンパイルされるソース・ファイルごとの情報が出力される、詳細出力を使用します。

-version

リリース情報を出力します。

-werror

警告が発生した場合にコンパイルを終了します。

-X

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

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

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

-target *version*

仮想マシンの指定されたリリースを対象とするクラス・ファイルを生成します。クラス・ファイルは、指定されたターゲット以降のリリースでは動作しますが、それより前のリリースのJVMでは動作しません。有効なターゲットは、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**オプションの値になります。

-bootclasspath *bootclasspath*

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

## コンパクト・プロファイル・オプション

JDK 8以降から、**javac**コンパイラはコンパクト・プロファイルをサポートします。コンパクト・プロファイルを使用すると、Javaプラットフォーム全体を必要としないアプリケーションは、デプロイ可能で、小さいフットプリントで実行できます。コンパクト・プロファイル機能は、アプリケーション・ストアからのアプリケーションのダウンロード時間を短縮するのに使用できます。この機能は、JREをバンドルするJavaアプリケーションの、よりコンパクトなデプロイメントに役立ちます。この機能は、小さいデバイスでも役立ちます。

サポートされているプロファイル値は、**compact1**、**compact2**および**compact3**です。これらは、追加のレイヤーです。大きい番号の各コンパクト・プロファイルには、小さい番号の名前のプロファイル内のすべてのAPIが含まれます。

-profile

コンパクト・プロファイルを使用する場合、このオプションは、コンパイル時にプロファイル名を指定します。次に例を示します。

```
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の完全なセットに対して実行されます。(どのコンパクト・プロファイルにも、**Applet**クラスは含まれていません。)

コンパクト・プロファイルを使用してコンパイルするための別の方法として、**-bootclasspath**オプションを使用して、プロファイルのイメージを指定する**rt.jar**ファイルへのパスを指定します。かわりに**-profile**オプションを使用すると、プロファイル・イメージは、コンパイル時にシステム上に存在する必要がありません。これは、クロスコンパイル時に役立ちます。

## 非標準オプション

-Xbootclasspath/p:*path*

ブートストラップ・クラス・パスに接尾辞を追加します。

-Xbootclasspath/a:*path*

ブートストラップ・クラス・パスに接頭辞を追加します。

-Xbootclasspath/:*path*

ブートストラップ・クラス・ファイルの位置をオーバーライドします。

-Xdoclint:\[-]*group* \[*/access*]

*group*の値が**accessibility**、**syntax**、**reference**、**html**または**missing**のいずれかである特定のチェック・グループを有効または無効にします。これらのチェック・グループの詳細は、**javadoc**コマンドの**-Xdoclint**オプションを参照してください。**-Xdoclint**オプションは、**javac**コマンドではデフォルトで無効になります。

変数*access*は、**-Xdoclint**オプションがチェックするクラスとメンバーの最小の可視性レベルを指定します。**public**、**protected**、**package**および**private**の値(可視性の高い順)の1つを持つことができます。たとえば、次のオプションは、(protected、package、publicを含む) protected以上のアクセス・レベルを持つクラスおよびメンバーを(すべてのチェック・グループで)チェックします。

```
-Xdoclint:all/protected


 
```

次のオプションは、package以上のアクセス権(packageおよびpublicを含む)を持つクラスおよびメンバーに対するHTMLエラーをチェックしないことを除き、すべてのアクセス・レベルに対してすべてのチェック・グループを有効にします。

```
-Xdoclint:all,-html/package


 
```

-Xdoclint:none

すべてのチェック・グループを無効にします。

-Xdoclint:all\[*/access*]

すべてのチェック・グループを有効にします。

-Xlint

推奨されるすべての警告を有効にします。このリリースでは、利用可能なすべての警告を有効にすることをお薦めします。

-Xlint:all

推奨されるすべての警告を有効にします。このリリースでは、利用可能なすべての警告を有効にすることをお薦めします。

-Xlint:none

すべての警告を無効にします。

-Xlint:*name*

警告名を無効にします。このオプションで無効にできる警告のリストは、-Xlintオプションを使用した警告の有効化または無効化を参照してください。

-Xlint:*-name*

警告名を無効にします。このオプションで無効にできる警告のリストを取得するには、-Xlintオプションを使用した警告の有効化または無効化-Xlint**オプションを使用した**を参照してください。

-Xmaxerrs *number*

印刷するエラーの最大数を設定します。

-Xmaxwarns *number*

印刷する警告の最大数を設定します。

-Xstdout *filename*

コンパイラのメッセージを、指定されたファイルに送信します。デフォルトでは、コンパイラのメッセージは**System.err**に送られます。

-Xprefer:\[*newer,source*]

ある型に対してソース・ファイルとクラス・ファイルの両方が見つかった場合、そのどちらのファイルを読み取るかを指定します。(型の検索を参照してください)。**-Xprefer:newer**オプションを使用した場合、ある型に対するソース・ファイルとクラス・ファイルのうち新しい方が読み取られます(デフォルト)。**-Xprefer:source**オプションを使用した場合、ソース・ファイルが読み取られます。**SOURCE**の保存ポリシーを使用して宣言された注釈に任意の注釈プロセッサがアクセスできるようにする場合は、**-Xprefer:source**を使用してください。

-Xpkginfo:\[*always*,*legacy*,*nonempty*]

javacがpackage-info.javaファイルから**package-info.class**ファイルを生成するかどうかを制御します。このオプションで使用可能なmode引数は次のとおりです。

always

すべての**package-info.java**ファイルの**package-info.class**ファイルを常に生成します。このオプションは、各**.java**ファイルに対応する**.class**ファイルがあることを確認するAntなどのビルド・システムを使用する場合に役立つことがあります。

legacy

package-info.javaに注釈が含まれる場合にのみ**package-info.class**ファイルを生成します。package-info.javaにコメントのみ含まれる場合に**package-info.class**ファイルを生成しません。

**注意:** **package-info.class**ファイルは生成できますが、package-info.javaファイル内のすべての注釈に**RetentionPolicy.SOURCE**がある場合は空になります。

nonempty

package-info.javaに**RetentionPolicy.CLASS**または**RetentionPolicy.RUNTIME**とともに注釈が含まれる場合にのみ**package-info.class**ファイルを生成します。

-Xprint

デバッグ目的で指定した型のテキスト表示を出力します。注釈処理もコンパイルも実行されません。出力形式は変更される可能性があります。

-XprintProcessorInfo

ある特定のプロセッサが処理を依頼されている注釈に関する情報を出力します。

-XprintRounds

初回および後続の注釈処理ラウンドに関する情報を出力します。

# [-XLINTオプションを使用した警告の有効化または無効化](#XLINT)

**-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();


 
```

メソッド**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**オプションが使用されていた場合、コンパイラは、問題になっているケースの行番号とともに、caseにfall-throughする可能性があることを示す警告を発行します。

finally

正常に完了できない**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**ブロックは実行される必要があるため、制御がメソッドの外部に移されていても、このブロックは実行されます。

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

path

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

```
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();
   }
}


 
```

**ソース・ファイル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&lt;?&gt;**は、アンバウンド形式のワイルドカードのパラメータ化された型です。**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&lt;Number&gt;**および**List&lt;String&gt;**は、それぞれ**ArrayList**および**List**になります。

**ls**コマンドには、パラメータ化された型**List&lt;String&gt;**が指定されています。**l**によって参照される**List**が**ls**に割り当てられた場合、コンパイラは未検査警告を生成します。コンパイル時に、コンパイラおよびJVMは、**l**が**List&lt;String&gt;**型を参照するかどうかを判別できません。この場合、**l**は、**List&lt;String&gt;**型を参照しません。その結果、ヒープ汚染が発生します。

ヒープ汚染状態が発生するのは、**List**オブジェクト**l** (そのstatic型は**List&lt;Number&gt;**)が別の**List**オブジェクト**ls** (異なるstatic型**List&lt;String&gt;**を持つ)に代入される場合です。しかし、コンパイラではこの代入をいまだに許可しています。総称をサポートしないJava SEのリリースとの後方互換性を確保するために、この代入を許可する必要があります。型の削除のため、**List&lt;Number&gt;**および**List&lt;String&gt;**は、両方**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...**要素を仮パラメータ**T\[]**要素(配列)に変換します。しかし、型消去により、コンパイラは**varargs**の仮パラメータを**Object\[]**要素に変換します。その結果、ヒープ汚染が発生する可能性があります。

# コマンド行引数ファイル

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

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

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

**javac**コマンドを実行するときに、各引数ファイルのパスと名前の先頭にアットマーク(@)文字を付けて渡します。**javac**コマンドは、アットマーク(@)で始まる引数を見つけると、そのファイルの内容を展開して引数リストに挿入します。

**例 1** 単一の引数ファイル

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

```
javac @argfile


 
```

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

**例 2** 2つの引数ファイル

**javac**オプション用とソース・ファイル名用に、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


 
```

**例 3** パスを使用した引数ファイル

引数ファイルはパスを指定できますが、ファイル内のすべてのファイル名は、(**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**オプションが使用されないかぎり、コンパイラは、元のソース・ファイルと生成されたすべてのソース・ファイルをコンパイルします。

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

コンパイラは、一連のソース・ファイルをコンパイルする際に、別のソース・ファイルを暗黙的にロードすることが必要な場合があります。型の検索を参照してください。そのようなファイルは、現時点では注釈処理の対象になりません。デフォルトでは、注釈処理が実行され、かつ暗黙的にロードされた任意のソース・ファイルがコンパイルされた場合、コンパイラは警告を発行します。**-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** 簡単なプログラムのコンパイル

この例では、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


 
```

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

この例では、**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


 
```

**例 3** ユーザー・クラス・パスの指定

前述の例のソース・ファイルのうち1つを変更した後に、そのファイルを再コンパイルします。

```
pwd
/examples
javac greetings/Hi.java


 
```

**greetings.Hi**は**greetings**パッケージ内の他のクラスを参照しているため、コンパイラはこれらの他のクラスを探す必要があります。デフォルトのユーザー・クラス・パスはパッケージ・ディレクトリを含むディレクトリであるため、前述の例は動作します。現在のディレクトリを気にせずにこのファイルを再コンパイルする場合、**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


 
```

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

次の例では、**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)で動作しない可能性があります。

**例 5** クロス・コンパイル

この例では、**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と互換性のあるクラス・ファイルが生成されます。

**-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)で動作しない可能性があります。この例では、コンパイラはJavaプログラミング言語のリリース1.7を使用します。

# 関連項目

•[java(1)](/man/os/openjdk-11/java.1)

•[jdb(1)](/man/os/openjdk-11/jdb.1)

•[javadoc(1)](/man/os/openjdk-11/javadoc.1)

•[jar(1)](/man/os/openjdk-11/jar.1)

•[jdb(1)](/man/os/openjdk-11/jdb.1)

2015年3月3日 JDK 8

---

Document: javac(1) from openjdk-11 11.0.33-r0 (Chainguard OS)
Source: https://github.com/openjdk/jdk11u.git
