通过JavaCompiler进行编译都是在当前目录下生成class文件而使用编译选项可以改变这个默认目录编译选项是一个元素为String类型的Iterable集合如我们可以使用如下代码在D盘根目录下生成class文件
Iterable options = ArraysasList(d d:\\);
JavaCompilerCompilationTask task = compilergetTask(null fileManager
diagnostics options null compilationUnits);
在上面的例子中options处的参数为null而要传递编译器的参数就需要将options传入
有时我们编译一个Java源程序文件而这个源程序文件需要另几个Java文件而这些Java文件又在另外一个目录那么这就需要为编译器指定这些文件所在的目录
Iterable options = ArraysasList(sourcepath d:\\src);
上面的代码指定的被编译Java文件所依赖的源文件所在的目录
三从内存中编译
JavaCompiler不仅可以编译硬盘上的Java文件而且还可以编译内存中的Java代码然后使用reflection来运行它们我们可以编写一个JavaSourceFromString类通过这个类可以输入Java源代码一但建立这个对象你可以向其中输入任意的Java代码然后编译和运行而且无需向硬盘上写class文件
import javalangreflect*;
import javaio*;
import javaxtools*;
import javaxtoolsJavaCompilerCompilationTask;
import javautil*;
import javanet*;
public class test_compilerapi
{
private static void compilerJava() throws Exception
{
JavaCompiler compiler = ToolProvidergetSystemJavaCompiler();
DiagnosticCollector diagnostics = new DiagnosticCollector();
// 定义一个StringWriter类用于写Java程序
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
// 开始写Java程序
outprintln(public class HelloWorld {);
outprintln( public static void main(String args[]) {);
outprintln( Systemoutprintln(\Hello World\););
outprintln( });
outprintln(});
outclose();
//为这段代码取个名子HelloWorld以便以后使用reflection调用
JavaFileObject file = new JavaSourceFromString(HelloWorld writertoString());
Iterable compilationUnits = ArraysasList(file);
JavaCompilerCompilationTask task = compilergetTask(null null
diagnostics null null compilationUnits);
boolean success = taskcall();
Systemoutprintln(Success: + success);
// 如果成功通过reflection执行这段Java程序
if (success)
{
Systemoutprintln(输出);
ClassforName(HelloWorld)getDeclaredMethod(main new Class[]
{ String[]class })invoke(null new Object[]
{ null });
Systemoutprintln(输出 );
}
}
public static void main(String args[]) throws Exception
{
compilerJava();
}
}
// 用于传递源程序的JavaSourceFromString类
class JavaSourceFromString extends SimpleJavaFileObject
{
final String code;
JavaSourceFromString(String name String code)
{
super(URIcreate(string:/// + namereplace( /)+ KindSOURCEextension) KindSOURCE);
thiscode = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
{
return code;
}
}
[] [] [] []