先週はjavax.tools.JavaCompilerインタフェースを使用してJavaのソースをコンパイルする方法について解説しました。しかし,先週説明した範囲ではjavacのメインクラスであるcom.sun.tools.javac.Mainクラスを直接使用するのとほとんど変わりませんでした。
そこで,今週からJavaCompilerインタフェースの特有の機能について紹介していきます。
基本的な使用法
JavaCompilerインタフェースの機能を活用するには,先週紹介したrunメソッドを使わずにコンパイルを行います。
その代わり,仮想的なファイルマネージャであるjavax.tools.StandardJavaFileManagerインタフェースと,コンパイルを行うタスクを表すJavaCompiler.CompilationTaskインタフェースを使用します。
CompilerAPISample4.java
まず,コンパイルするJavaのソースファイルを準備する部分を示します。
// コンパイラの取得
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 仮想ファイルマネージャの取得
StandardJavaFileManager fileManager
= compiler.getStandardFileManager(null, null, null);
// コンパイルするファイルの準備
Iterable<? extends JavaFileObject> fileobjs =
fileManager.getJavaFileObjects("Hello.java");
JavaCompilerオブジェクトは先週紹介したように,javax.tools.ToolProviderクラスのgetSystemJavaCompilerメソッドを使用して取得します。
StandardJavaFileManagerインタフェースは,抽象的なファイルを表すjavax.tools.JavaFileObjectインタフェースを操作するためのインタフェースです。このJavaFileObjectインタフェースはFileクラスに対応するインタフェースです。
StandardJavaFileManagerインタフェースのオブジェクトは,青字で示したようにJavaCompilerインタフェースのgetStandardFileManagerメソッドを使用することで取得できます。
StandardJavaFileManagerオブジェクトを取得するためのgetStandardFileManagerメソッドの第1引数はコンパイルエラーに関するDiagnosticListenerオブジェクトを指定します。このDiagnosticListenerインタフェースについては後述します。
第2引数はロケール(java.util.Localeクラス),第3引数は文字セット(java.nio.charset.Charsetクラス)を指定します。
いずれの引数もnullを指定することで,デフォルトの値が適用されます。つまり,ロケールはデフォルトロケール,文字セットはプラットフォームのデフォルトの文字セットが使用されます。ここでは,すべてnullとしています。
次に,コンパイルするJavaのソースファイルに対するJavaFileObjectオブジェクトを取得します(赤字部分)。
CompilationTaskインタフェースで扱うソースファイルはJavaFileObjectオブジェクトで表します。そのため,実際のソースファイルに対応するJavaFileObjectオブジェクトを取得する必要があるのです。
JavaFileObjectオブジェクトを取得するにはStandardJavaFileManagerインタフェースのgetJavaFileObjectsメソッドを使用します。getJavaFileObjectsメソッドには引数が文字列のものとFileオブジェクトのものがあります。いずれも,可変引数になっているので,コンパイルするファイルを列挙します。
これ以外に,コレクションを引数に取れるgetJavaFileObjectsFromStringsメソッドもしくはgetJavaFileObjectsFromFilesメソッドも提供されています。
これらのメソッドの戻り値の型はいずれもIterable<? extends JavaFileObject>です。java.lang.IterableインタフェースはJ2SE 5.0で導入された拡張for文で使用するためのインタフェースです。
Listオブジェクトなどを拡張for文で扱えるのは,java.util.CollectionインタフェースがIterableインタフェースの派生インタフェースだからなのです。