动态编译和执行都可以使用runtime方法在此不讲
动态编译
- 使用JavaCompiler方法进行编译
//动态编译
String path="g:/dynamic/first.java"; //路径
JavaCompiler compiler=ToolProvider.getSystemJavaCompiler(); //调用动态编译的工具
int result =compiler.run(null,null, null, path); //进行动态编译,并返回结果
System.out.println(result==0?"编译成功":"编译失败");
动态运行
实用类加载器进行操作(之后会专门讲类加载器)
1、首先构建文件的目录url地址,
2、使用URLClassLoader对象的loadClass方法加载对应类
3、获取所加载类的方法
4、传入方法所需的参数通过invoke运行方法
//通过反射方法动态执行
//1、首先构建文件的目录url地址,
URL[] urls =new URL[] {new URL("file:/"+"g:/dynamic/")};
//2、使用URLClassLoader对象的loadClass方法加载对应类
URLClassLoader loder=new URLClassLoader(urls);
//3、获取所加载类的方法
Class clazz =loder.loadClass("first");
// 4、传入方法所需的参数通过invoke运行方法
Method method=clazz.getDeclaredMethod("main", String[].class);
method.invoke(null, (Object)new String[] {}); //当类型为String[]时,需要(Object)new String[] {}初始化
注意点
1、在构建URL时候一定要是URL数组。因为new URLClassLoader() 只支持URL[]的参数
2、 在使用loader.loadClass()时,传入的为类名,不要加.class后缀
3、在使用Method对象的getDeclaredMethod()方法时候第一个参数为获取方法的名字,第二个参数为本方法传入参数的类型
4、执行invoke()方法时,第一个参数为方法的返回类型。第二个参数为一个对象,例如main方法中的String[]
args,它本身是一个数组,若不将其强制转换为Object,会产生异常:
完整代码
package 动态编译;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class dynamic1 {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//动态编译
String path="g:/dynamic/first.java"; //路径
JavaCompiler compiler=ToolProvider.getSystemJavaCompiler(); //调用动态编译的工具
int result =compiler.run(null,null, null, path); //进行动态编译,并返回结果
System.out.println(result==0?"编译成功":"编译失败");
//通过反射方法动态执行
//1、首先构建文件的目录url地址,
URL[] urls =new URL[] {new URL("file:/"+"g:/dynamic/")};
//2、使用URLClassLoader对象的loadClass方法加载对应类
URLClassLoader loder=new URLClassLoader(urls);
//3、获取所加载类的方法
Class clazz =loder.loadClass("first");
// 4、传入方法所需的参数通过invoke运行方法
Method method=clazz.getDeclaredMethod("main", String[].class);
method.invoke(null, (Object)new String[] {}); //当类型为String[]时,需要(Object)new String[] {}初始化
}
}
- 被动态编译带类是 start 作用复制一张图片