1、只要是在本地静态编译能够实现的任务,比如编译参数、输入输出、错误监控等,动态编译就都能实现。
2、Java 的动态编译对源提供了多个渠道。比如, 可以是字符串( 例子中就是字符
串),可以是文本文件,也可以是编译过的字节码文件(.class 文件),只要是符合Java 规范的就都可以在运行期动态加载, 其实现方式就是实现JavaFileObject 接口, 重写getCharContent、openInputStream、openOutputStream,或者实现JDK 已经提供的两个实现类SimpleJavaFileObject、ForwardingJavaFileObject,具体代码可以参考如下的例子。
package xjt.gone;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class JIT {
public static void main(String[] args)throws Exception{
// 类名
String clsName = "Hello";
// 方法名
String methodName = "sayHello";
// 当前编译器
JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
//Java 标准文件管理器
StandardJavaFileManager fm = cmp.getStandardFileManager(null,null,null);
//Java 文件对象
XJavaFileObject jfo = new XJavaFileObject(new File("D:/Hello.java"),Kind.SOURCE);
// 编译参数,类似于javac <options> 中的options
List<String> optionsList = new ArrayList<String>();
// 编译文件的存放地方
optionsList.addAll(Arrays.asList("-d","F:/sth/myeclipse/gone/WebRoot/WEB-INF/classes"));
// 要编译的单元
List<XJavaFileObject> jfos = Arrays.asList(jfo);
// 设置编译环境
JavaCompiler.CompilationTask task = cmp.getTask(null, fm, null,
optionsList,null,jfos);
if(task.call()){
// 生成对象
Object obj = Class.forName(clsName).newInstance();
Class<? extends Object> cls = obj.getClass();
// 调用sayHello 方法
Method m = cls.getMethod(methodName);
String str = (String) m.invoke(obj);
System.out.println(str);
}
}
}
package xjt.gone;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.tools.SimpleJavaFileObject;
public class XJavaFileObject extends SimpleJavaFileObject {
private File file;
public XJavaFileObject(File file, Kind kind) {
super(file.toURI(), kind);
this.file = file;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
throws IOException {
StringBuffer sb = new StringBuffer();
FileReader fReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fReader);
String s = null;
while ((s=bufferedReader.readLine())!=null) {
sb.append(s);
}
bufferedReader.close();
return sb.toString();
}
}
public class Hello {
public String sayHello(){
System.out.println("逝者如斯");
return "2";
}
}