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

5 篇文章 0 订阅

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值