java SE 6中的动态编译
今天简单学习了下java SE下的动态编译方式,写了一个小小的demo,用来参考
public class JavaCompilerTest {
/**
* @param args
* main方法
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
test("Test.java");
}
/**
* @param clazzName
* 类名
* @throws Exception
*此处异常为了简便,只是简单抛出 读入一个java文件,并编译,加载类,生成对象,使用反射调用方法*/
public static void test(String clazzName) throws Exception {
// 使用StringBuilder来保存一个类,当然,也可以自己通过参数传过来
// 使用StringBuilder的原因是StringBuilder比StringBuffer快,用于单线程情况
// StringBuffer用于多线程安全的情况,详情见jdk文档
StringBuilder str = new StringBuilder();
str.append("public class Test {" + "\n");
str.append("public void test() {" + "\n");
str.append("System.out.println(\"Compiler success! \");" + "\n");
str.append("}" + "\n");
str.append("}");
// 将java文件写入src文件夹下
FileOutputStream fo = new FileOutputStream("src/" + clazzName);
fo.write(str.toString().getBytes());// 直接写入文件
fo.flush();
fo.close();// 关闭流
System.out.println(System.getProperty("user.dir"));
// 获取编译器,如果使用eclipse开发工具,此处易报Nullpointer错误,解决方法见我的另一篇文章
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
int state = 1;// 保存编译返回的状态,0编译成功,非0编译失败
try {
//编译类文件,输出到bin文件夹下
state = javac.run(System.in, System.out, System.err, "-d",
System.getProperty("user.dir") + "\\bin",
System.getProperty("user.dir") + "\\src\\Test.java");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (state != 0) {
System.out.println("compiler failed!");
System.exit(0);
}
//通过类名加载类
Class> clazz = Class.forName("Test");
//获取类的方法,test方法无参数,所以getDeclaredMethod后面的参数省略
Method method = clazz.getDeclaredMethod("test");
//调用对应的方法
method.invoke(clazz.newInstance());
}
}