在这段代码中多写了个aa,得到的编译错误为:

Code: compiler.err.not.stmt

Kind: ERROR

Position: 89

Start Position: 89

End Position: 89

Source: test.java

Message: test.java:5: 不是语句

Success: false

通过JavaCompiler进行编译都是在当前目录下生成.class文件,而使用编译选项可以改变这个默认目录。编译选项是一个元素为String类型的Iterable集合。如我们可以使用如下代码在D盘根目录下生成.class文件。

Iterable options = Arrays.asList("-d", "d:\\");

JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,

diagnostics, options, null, compilationUnits);

在上面的例子中options处的参数为null,而要传递编译器的参数,就需要将options传入。

有时我们编译一个Java源程序文件,而这个源程序文件需要另几个Java文件,而这些Java文件又在另外一个目录,那么这就需要为编译器指定这些文件所在的目录。

Iterable options = Arrays.asList("-sourcepath", "d:\\src");

上面的代码指定的被编译Java文件所依赖的源文件所在的目录。

三、从内存中编译

JavaCompiler不仅可以编译硬盘上的Java文件,而且还可以编译内存中的Java代码,然后使用reflection来运行它们。我们可以编写一个JavaSourceFromString类,通过这个类可以输入Java源代码。一但建立这个对象,你可以向其中输入任意的Java代码,然后编译和运行,而且无需向硬盘上写.class文件。

import java.lang.reflect.*;

import java.io.*;

import javax.tools.*;

import javax.tools.JavaCompiler.CompilationTask;

import java.util.*;

import java.net.*;

public class test_compilerapi

{

 private static void compilerJava() throws Exception

 {

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

DiagnosticCollector diagnostics = new DiagnosticCollector();

// 定义一个StringWriter类,用于写Java程序

StringWriter writer = new StringWriter();

PrintWriter out = new PrintWriter(writer);

// 开始写Java程序

out.println("public class HelloWorld {");

out.println(" public static void main(String args[]) {");

out.println(" System.out.println(\"Hello, World\");");

out.println(" }");

out.println("}");

out.close();

//为这段代码取个名子:HelloWorld,以便以后使用reflection调用

JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());

Iterable compilationUnits = Arrays.asList(file);

JavaCompiler.CompilationTask task = compiler.getTask(null, null,

 diagnostics, null, null, compilationUnits);

boolean success = task.call();

System.out.println("Success: " + success);

// 如果成功,通过reflection执行这段Java程序

if (success)

{

 System.out.println("-----输出-----");

 Class.forName("HelloWorld").getDeclaredMethod("main", new Class[]

{ String[].class }).invoke(null, new Object[]

{ null });

 System.out.println("-----输出 -----");

}

 }

 public static void main(String args[]) throws Exception

 {

compilerJava();

 }

}

// 用于传递源程序的JavaSourceFromString类

class JavaSourceFromString extends SimpleJavaFileObject

{

 final String code;

 JavaSourceFromString(String name, String code)

 {

super(URI.create("string:///" + name.replace('.', '/')+ Kind.SOURCE.extension), Kind.SOURCE);

this.code = code;

 }

 @Override

 public CharSequence getCharContent(boolean ignoreEncodingErrors)

 {

return code;

 }

}