023-JVM-类加载器源码分析

395 阅读2分钟
package com.yuhl.c2020;

/**
 * @author yuhl
 * @Date 2020/12/22 21:27
 * @Classname LoadClassResource
 * @Description TODO
 */
public class LoadClassResource {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = LoadClassResource.class.getClassLoader().loadClass("com.yuhl.c2020.Miao");
        System.out.println(clazz.getName());
    }
}

调用

public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }
// name = com.yuhl.c2020.Miao
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
    //调用之前先加锁,说明是线程安全的
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            // 这里特别注意,先查找内存中是否已经存在(已经加载过了)
            Class<?> c = findLoadedClass(name);
            //乳沟没有加载过则则进行下面的操作
            if (c == null) {
                long t0 = System.nanoTime();
                try {
	                //如果没有加载过,则获得当前类加载器的parent 成员变量,即向上传递,开始双亲委派
	                //如果parent不为空则有parent重新这个方法的过程
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                    	//要不然交给Bootstrap处理加载 调用private native Class<?> findBootstrapClass(String name); 有jvm调用处理
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

				//如果依然没有加载,则有findClass ()方法
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    /**
                    此处的findClass()方法即为用户自定义的方法,你看过来就是跑一场,也就是我们自定义类加载器的时候写这个findClass 方法即可!
                      protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
                    */
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
  1. 源码可以看到双亲委派的具体代码实现
  2. 如果需要自定义类加载器的话需要重写 findClass() 方法

自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!
自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!
自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!