主要体现在ClassLoader的loadClass()方法中,思路很简单:先检查是否已经被加载过,若没有加载则调用父类加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父类加载器。如果父类加载器加载失败,抛出ClassNotFoundException异常后,调用自己的findClass()方法进行加载。
四、JavaCompiler动态编译
使用JavaCompiler进行动态编译。
//使用ToolProvider.getSystemJavaCompiler来得到一个JavaCompiler接口的实例。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//JavaCompiler中最核心的方法是run()。通过这个方法能编译java源代码。
int run(InputStream in, OutputStream out, OutputStream err, String… arguments)
参数分别用来为:
-
java编译器提供参数
-
得到Java编译器的输出信息
-
接收编译器的错误信息,
-
一个或多个Java源程式文件
如果run编译成功,返回 0。
如果前3个参数传入的是null
,那么run方法将以标准的输入、输出代替,即System.in
、System.out
和System.err
。如果我们要编译一个test.java
文件,并将使用标准输入输出,run的使用方法如下:
int results = tool.run(null, null, null, “D:\test\Student.java”);
五、通过URLClassLoader加载程序外的jar包,并进行动态编译
1、实体类Student
package com.guor.bean;
public class Student {
public Integer id;
public String name;
public void hello(String param) {
System.out.println(param);
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “Student [id=” + id + “, name=” + name + “]”;
}
}
2、Java文件 -> class -> jar -> 动态编辑 -> 反射赋值
private void test01() throws Exception {
final String javaPath = “D:\test\java”;
final String studentPath = javaPath + “\Student.java”;
final String jarPath = “D:\test\jar\student-1.0.0.jar”;
final String packageStudentPath = “com.guor.bean.Student”;
// 将java源文件编译成.class字节码文件
String cmd = "javac " + studentPath;
System.out.println(cmd);
boolean execSysCmd = execCmd(cmd);
System.out.println(execSysCmd);
// 打成jar包
cmd = "jar -cvf " + jarPath + " " + javaPath;
System.out.println(cmd);
execSysCmd = execCmd(cmd);
System.out.println(execSysCmd);
/**
-
URLClassLoader:继承自SecureClassLoader,支持从jar文件和文件夹中获取class,
-
继承于classload,加载时首先去classload里判断是否由bootstrap classload加载过
*/
URL url = new URL(“file:” + jarPath);
URLClassLoader classLoader = new URLClassLoader(new URL[] { url },
Thread.currentThread().getContextClassLoader());
CusCompiler compiler = new CusCompiler(classLoader);
File file = new File(studentPath);<