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 List optionsList = new ArrayList (); // 编译文件的存放地方 optionsList.addAll(Arrays.asList("-d","F:/sth/myeclipse/gone/WebRoot/WEB-INF/classes")); // 要编译的单元 List 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 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(); }}
Hello.java
public class Hello { public String sayHello(){ System.out.println("逝者如斯"); return "2"; }}