概述:
Java的动态编译就是在运行期直接编译.java文件,执行.class,并且能够获得相关的输入输出,甚至还能监听相关的事件。
步骤:
1、创建或自动生成.java文件
2、调用JavaCompiler获取编译器,该类允许开发人员编译java文件为class文件
JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();
3、获取文件管理器StandardJavaFileManager,用来管理要编译的.java文件。getStandardFileManager有3个参数,分别代表监听器、语言环境、字符集
StandardJavaFileManager fileManger = compiler.getStandardFileManager(null, null, null);
4、获取表示给定文件的文件对象
Iterable unils = fileManger.getJavaFileObjects(fileName)
5、获取编译任务的future接口CompilationTask,当调用它的call方法时,开始编译
CompilationTask t = compiler.getTask(null, fileManger, null, null, null, unils);
t.call();
6、调用URLClassLoader将编译的文件load内存,其中需要知道文件的位置,用URL记录,其中“file:/”表示本地文件。
URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/scr")};
URLClassLoader cl = new URLClassLoader(urls);
7、获取编译后的类
Class c = cl.loadClass("com.chensr.util.function.Function");
8、获取构造函数,构造方法如果有参数需要配置对应的参数类型
Constructor constructor = c.getConstructor(String.class);
Object b =constructor.newInstance("哈哈");
9、执行对应的方法
Method method=c.getDeclaredMethod("方法名","参数类型");
method.invoke(b,"参数值");
具体代码如下:
packagecom.chensr.util.function;importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;importjava.lang.reflect.Constructor;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.net.URL;importjava.net.URLClassLoader;importjavax.tools.JavaCompiler;importjavax.tools.JavaCompiler.CompilationTask;importjavax.tools.StandardJavaFileManager;importjavax.tools.ToolProvider;public classReflection {public static void main(String[] args) throwsException {
String str="package com.chensr.util.function; \r\t"+
"public class Function { \r\t"+
" public Function(String a) { \r\t"+
" System.out.println(\"我是构造函数!\"+a);\r\t"+
" }\r\t"+
" public static void say(){ \r\t"+
" System.out.println(\"我由string生成class\");\r\t"+
" }\r\t"+
"}";//根据str生成.java文件
String fileName=System.getProperty("user.dir")+
"\\src\\main\\java\\com\\chensr\\util\\function\\Function.java";
System.out.println(fileName);
File file= newFile(fileName);
FileWriter fw= newFileWriter(file);
fw.write(str);
fw.flush();
fw.close();//调用JavaCompiler获取编译器,该类允许开发人员编译java文件为class文件
JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();//Java 标准文件管理器,第一个参数为监听器,第二个参数语音环境,第三个参数为字符集
StandardJavaFileManager fileManger = compiler.getStandardFileManager(null, null, null);//获取表示给定文件的文件对象
Iterable unils =fileManger.getJavaFileObjects(fileName);//CompilationTask表示编译任务的未来的接口。调用call()启动任务。getTask方法编译源代码,并将对应的class文件生成到指定目录CompilationTask t= compiler.getTask(null, fileManger, null, null, null, unils);
t.call();
fileManger.close();//load内存,并且创建一个实例
URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/scr")};
URLClassLoader cl = newURLClassLoader(urls);
Class c= cl.loadClass("com.chensr.util.function.Function");//获取构造函数和执行对应的方法
Constructor constructor = c.getConstructor(String.class);
Object b=constructor.newInstance("哈哈");
Method method=c.getDeclaredMethod("say");
method.invoke(b);
}
}