ClassLoader和UrlClassLoader源码分析

本文深入分析了Java的ClassLoader体系,包括基类ClassLoader、AppClassLoader、ExtClassLoader以及重要的URLClassLoader。详细讲解了类加载的过程,特别是双亲委派机制,并探讨了URLClassLoader如何从指定URL加载类。
摘要由CSDN通过智能技术生成

1、一切的基类:ClassLoader

在java中存在4种类加载器,分别是启动类加载器、扩展类加载器、系统类加载器和自定义加载器,而AppClassLoader就是其中的系统类加载器。AppClassLoader系统类加载器中包含一个parent指针指向扩展类加载器ExtClassLoader,ExtClassLoader中的parent指针指向为空,因为其上一层为启动类加载器,启动类加载器是用C++写的,因此在java中没有启动类加载器。
在我们一般代码中默认的类加载器就是系统类加载器AppClassLoader,但是无论是AppClassLoader还是ExtClassLoader,他们都继承自基类ClassLoader,注意,在ClassLoader中存在一个成员变量parent,该变量指向了自己名义上的双亲

public abstract class ClassLoader {
   
    //指向自己的双亲
    private final java.lang.ClassLoader parent;
}

在ClassLoader中有一个非常重要的方法叫做loadClass程序运行过程中加载类的操作就是通过这个函数来实现的,同时也是满足双亲委派机制,loadClass方法核心代码如下:

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
   
    synchronized (getClassLoadingLock(name)) {
   
        // 1、首先判断当前类加载器是否已经加载过该类
        Class<?> c = findLoadedClass(name);
        if (c == null) {
   
            long t0 = System.nanoTime();
            try {
   
                if (parent != null) {
   
                  //2、利用父加载器进行递归加载
                    c = parent.loadClass(name, false);
                } else {
   
                  //3、如果父加载器为空则采用启动类加载器加载,没有则返回空
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
   
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }

            if (c == null) {
   
              //4、如果通过父加载器和启动类加载器都没有找到,则通过findClass寻找
                long t1 = System.nanoTime();
                c = findClass(name);
            }
        }
        return c;
    }
}

如上代码所示,当Java中加载一个类时会经历以下步骤:

  • 首先判断当前类加载器是否已经加载了该类=>Class<?> c = findLoadedClass(name);
  • 然后通过parent指针找到自己的双亲,然后递归调用parent的loadClass方法来让父类先加载,从而实现双亲委派机制。=>c = parent.loadClass(name, false);
  • 如果parent为空(说明当前ClassLoader为ExtClassLoader),则通过本地方法直接调用启动类加载器来加载该类=>c = findBootstrapClassOrNull(name);
  • 如果当前类加载器的父类都未能成功加载该类,则通过findClass函数自己来加载该类=>c=findClass(name)


注意,对于基类ClassLoader而言,它并没有实现findClass方法,而是将这个方法交给了自己的子类去实现,系统类加载器和扩展类加载器都实现了这个方法。

protected Class<?> findClass(String name) throws ClassNotFoundException {
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值