您的位置:首页 > 编程语言 > Java开发

Java-Classloader-loadeClass(String,boolean)、findClass(String)类加载源码解析

2017-10-08 10:22 841 查看
这里为了更好的说明类加载的过程,将部分次要代码删去,若有兴趣,可以自行查看Classloder源码

首先我们先来简述一下类加载的过程

使用findLoadedClass(name)方法查看该类是否已经被加载

如果该类未被加载过,则调用他的父类加载器,这里的父类加载器是扩展类加载器

扩展类加载器同样是继承ClassLoader类,因为它存在父类加载器就是引导类加载器,所以在执行loadClass方法时,同样会将加载委派给他的父类引导类加载器来执行

轮到引导类加载器的时候,由于它是加载器的最高一级,没有父类了,所以他就调用自身也就是引导类加载器的类加载方法

如果引导类加载不了,则会一层层往下退,先交给扩展类加载器,同理如果拓展类加载器还是加载不了,则会交给应用程序类加载类,如果还是加载不了,则最终会回到用户自定义的类加载器执行用户重写的findClass(String)方法

所以用户自定义类加载器的时候要重写findClass(String)方法而不是loadClass方法

protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
//同步锁保证类加载是线程安全的
synchronized (getClassLoadingLock(name)) {
//查看该类是否已经被加载
Class<?> c = findLoadedClass(name);
//该类未被加载过
if (c == null) {
try {
//当前加载器存在父类加载器
if (parent != null) {
//调用委派的父类加载器执行该类的加载
c = parent.loadClass(name, false);
} else {
//当前加载器不存在父类加载器
//就委派最高级的引导类加载器来进行类的加载
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
//如果父类加载器都执行不了
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class
//就调用自定义的类加载器来执行加载
c = findClass(name);
}
}
//如果确认该类已经被加载,则直接链接到指定的类
if (resolve) {
resolveClass(c);
}
return c;
}
}


//用户在自定义类加载器的时候通常需要继承java.lang.ClassLoader并重写该方法
//该方法会内loadClass(String,boolean)方法调用
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐