03 类加载机制解析二:自定义类加载器

tech2022-08-19  82

文章目录

1 自定义类加载器

1 自定义类加载器

自定义类加载器只需要继承 java.lang.ClassLoader 类,该类有两个核心方法,一个是 loadClass(String, boolean),实现了双亲委派机制,还有一个方法是findClass,默认实现是空方法,所以我们自定义类加载器主要是重写findClass方法。

自定义类加载器MyClassLoader package study.wyy.jvm.classLoader; import java.io.FileInputStream; public class MyClassLoader extends ClassLoader { private String classPath; public MyClassLoader(String classPath) { this.classPath = classPath; } private byte[] loadByte(String name) throws Exception { name = name.replaceAll("\\.", "/"); FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class"); int len = fis.available(); byte[] data = new byte[len]; fis.read(data); fis.close(); return data; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { byte[] bytes = loadByte(name); return defineClass(name,bytes,0,bytes.length); } catch (Exception e) { e.printStackTrace(); throw new ClassNotFoundException(); } } } 测试定义一个目标类,使用我们的自定义加载器去加载 package study.wyy.jvm.model; public class TargetClass { void sayHello(){ System.out.println("say hello"); } } idea编译之后,将这个类的class文件放到/Users/wyaoyao/Documents/test下 package study.wyy.jvm.classLoader; public class MyClassLoaderTest { public static void main(String[] args) throws Exception { //初始化自定义类加载器,会先初始化父类ClassLoader,其中会把自定义类加载器的父加载器设置为应用程序类加载器AppClassLoader, 指定MyClassLoader加载的路径为/Users/wyaoyao/Documents/test MyClassLoader classLoader = new MyClassLoader("/Users/wyaoyao/Documents/test"); //test目录创建 study.wyy.jvm.model 几级目录,将TargetClass类的class文件TargetClass.class丢入该目录 Class clazz = classLoader.loadClass("study.wyy.jvm.model.TargetClass"); System.out.println(clazz.getClassLoader().getClass().getName()); } }

输出:

sun.misc.Launcher$AppClassLoader

为啥是AppClassLoader,而不是我们的MyClassLoader?

k理解了双亲委派机制,这个就很好理解了

我们自己定义的MyClassLoader,去加载的时候TargetClass,会先委派它的父加载器AppClassLoader去加载,这个时候AppClassLoader也能加载到(idea的target目录下也有这么一个class),既然父加载器AppClassLoader加载到,就会返回。所以是AppClassLoader

如何让MyClassLoader去加载呢

删除idea的target目录下的TargetClass.class,这样AppClassLoader就加载不到,就会交给MyClassLoader去加载/Users/wyaoyao/Documents/test这个目录下的TargetClass.class

是否对双亲委派机制有了比较感观的认识了!!!

最新回复(0)