public class testa {
public static void main(string[] args) {
testa testa = new testa();
testa.hello();
}
public void hello() {
// https://jinglingwang.cn/archives/class-isolation-loading
system.out.println("testa: " + this.getclass().getclassloader());
testb testb = new testb();
testb.hello();
}
}
public class testb {
public void hello() {
system.out.println("testb: " + this.getclass().getclassloader());
}
}
然后重写一下 findclass 方法,这个方法先根据文件路径加载 class 文件,然后调用 defineclass 获取 class 对象。
public class myclassloaderparentfirst extends classloader{
private map<string, string> classpathmap = new hashmap<>();
public myclassloaderparentfirst() {
classpathmap.put("com.java.loader.testa", "/users/hansong/ideaprojects/ohmyjava/coderepository/target/classes/com/java/loader/testa.class");
classpathmap.put("com.java.loader.testb", "/users/hansong/ideaprojects/ohmyjava/coderepository/target/classes/com/java/loader/testb.class");
}
// 重写了 findclass 方法 by:jinglingwang.cn
@override
public class<?> findclass(string name) throws classnotfoundexception {
string classpath = classpathmap.get(name);
file file = new file(classpath);
if (!file.exists()) {
throw new classnotfoundexception();
}
byte[] classbytes = getclassdata(file);
if (classbytes == null || classbytes.length == 0) {
throw new classnotfoundexception();
}
return defineclass(classbytes, 0, classbytes.length);
}
private byte[] getclassdata(file file) {
try (inputstream ins = new fileinputstream(file); bytearrayoutputstream baos = new
bytearrayoutputstream()) {
byte[] buffer = new byte[4096];
int bytesnumread = 0;
while ((bytesnumread = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesnumread);
}
return baos.tobytearray();
} catch (filenotfoundexception e) {
e.printstacktrace();
} catch (ioexception e) {
e.printstacktrace();
}
return new byte[] {};
}
}
最后写一个 main 方法调用自定义的类加载器加载 testa,然后通过反射调用 testa 的 main 方法打印类加载器的信息。
public class mytest {
public static void main(string[] args) throws exception {
myclassloaderparentfirst myclassloaderparentfirst = new myclassloaderparentfirst();
class testaclass = myclassloaderparentfirst.findclass("com.java.loader.testa");
method mainmethod = testaclass.getdeclaredmethod("main", string[].class);
mainmethod.invoke(null, new object[]{args});
}