--- icon: edit date: 2023-02-17 category: - Java headerDepth: 5 --- # java 动态执行代码,可以从数据库·拉代码执行的方式例子 ```DynamicJavaCompilerUtil.java``` ```java import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.stream.Collectors; public class DynamicJavaCompilerUtil { static String tmpPath = "./tmp"; public static void Test() throws IOException { String code = new String("public class T4{ " + "static void print(String a){ " + "System.out.println(\"Hello world! \"+ a);" + "}" + "static void print(){ " + "System.out.println(\"Hello world! \");" + "}" + "static void print(Integer a,String b){ " + "System.out.println(\"Hello world! \"+a+b);" + "}" + "}"); CompilerToRun(code, "T4", "print", 1, " 2"); } /* * @param Code 代码字符串 * @param ClassName 类名 * @param MethodName 需要执行的方法名 * @param MethodParam 需要执行的方法的参数 */ public static void CompilerToRun(String Code, String ClassName, String MethodName, Object... MethodParam) throws IOException { isDirExists(new File(tmpPath)); File file = new File(tmpPath + "/" + ClassName + ".java"); RandomAccessFile accessFile = null; try { accessFile = new RandomAccessFile(file, "rw"); accessFile.write(Code.getBytes()); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //调用动态编译的工具 int result = compiler.run(null, null, null, tmpPath + "/" + ClassName + ".java"); //进行动态编译,并返回结果 if (result != 0) { throw new RuntimeException("编译失败"); } //通过反射方法动态执行 //1、首先构建文件的目录url地址, URL[] urls = new URL[]{new URL("file:" + tmpPath + "/")}; //2、使用URLClassLoader对象的loadClass方法加载对应类 URLClassLoader loder = new URLClassLoader(urls); //3、获取所加载类的方法 Class clazz = loder.loadClass(ClassName); Class[] MethodParamClass = Arrays.asList(MethodParam).stream().map(Object::getClass).collect(Collectors.toList()).toArray(new Class[]{}); // 4、传入方法所需的参数通过invoke运行方法 Method method = clazz.getDeclaredMethod(MethodName, MethodParamClass); method.setAccessible(true); method.invoke(null, MethodParam); //当类型为String[]时,需要(Object)new String[] {}初始化 } catch (IOException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } finally { accessFile.close(); deleteFile(new File(tmpPath)); } } private static void isDirExists(File file) { if (!file.exists()) { file.mkdir(); } } private static Boolean deleteFile(File file) { //判断文件不为null或文件目录存在 if (file == null || !file.exists()) { System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确"); return false; } //获取目录下子文件 File[] files = file.listFiles(); //遍历该目录下的文件对象 for (File f : files) { //判断子目录是否存在子目录,如果是文件则删除 if (f.isDirectory()) { //递归删除目录下的文件 deleteFile(f); } else { //文件删除 f.delete(); //打印文件名 System.out.println("文件名:" + f.getName()); } } //文件夹删除 file.delete(); System.out.println("目录名:" + file.getName()); return true; } } ```