java的ClassLoader

本文深入解析Java中的ClassLoader机制,包括BootstrapClassLoader、ExtensionClassLoader和SystemClassLoader的工作原理及其构造过程。介绍了不同类型的类加载器之间的关系及类加载过程中的双亲委派机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java有两种类型的classload,一种是user-defined的,一种是jvm内置的bootstrap class loader,所有user-defined的class loader都是java.lang.ClassLoader的子类.

而jvm内置的class loader有3种,分别是 Bootstrap ClassLoader, Extension ClassLoader(即ExtClassLoader),System ClassLoader(即AppClassLoader).

而jvm加载时的双亲委派 就不说了,javaeye上有很多文章都有介绍..
可以分别看一下他们的构造器,其中Bootstrap ClassLoader是用c写的.
java.lang.ClassLoader
[code]
protected ClassLoader(ClassLoader parent) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
//给父loader赋值.
this.parent = parent;
initialized = true;
}
protected ClassLoader() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
//这边将会把AppClassLoader付给父loader
this.parent = getSystemClassLoader();
initialized = true;
}
[/code]
这个构造器有带参数的,和不带构造器的2个。带参数的构造器传入的是这个 class loader的父loader,而不带参数的构造器则会把getSystemClassLoader()所返回的class loader当作他自己的父装载器.下面我们来看getSystemClassLoader()的代码
[code]
public static ClassLoader getSystemClassLoader() {
//所返回的class loader在这个方法里面被赋值
initSystemClassLoader();
if (scl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = getCallerClassLoader();
if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
return scl;
}

private static synchronized void initSystemClassLoader() {
if (!sclSet) {
if (scl != null)
throw new IllegalStateException("recursive invocation");
sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
Throwable oops = null;
//在这边被赋值
scl = l.getClassLoader();
...................................
.......................................
}
}
sclSet = true;
}
}[/code]
这边的父class loader就是scl,也就是l.getClassLoader()所得到的,getClassLoader(),接下来看Launcher的源码:
[code]
private static Launcher launcher = new Launcher();

public static Launcher getLauncher() {
return launcher;
}

private ClassLoader loader;

public Launcher() {
// Create the extension class loader
ClassLoader extcl;
try {
//这里传入构造器的parent为空
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
"Could not create extension class loader");
}

// Now create the class loader to use to launch the application
try {
//这边可以看到默认的loader就是AppClassLoader,也就是说getSystemClassLoader返回的就是AppClassLoader
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader");
}
//每一个当前线程一个classload,以防止多线程中的classload引起的混乱(这个是我自己理解的,呵呵)
// Also set the context class loader for the primordial thread.
Thread.currentThread().setContextClassLoader(loader);

...................................
................................................
}

/*
* Returns the class loader used to launch the main application.
*/
public ClassLoader getClassLoader() {
return loader;
}
[/code]
从中我们看到AppClassLoader的父loader是ExtClassLoader,而ExtClassLoader的父loader是什么呢?我们在来看ExtClassLoader的构造器:
[code]
public ExtClassLoader(File[] dirs) throws IOException {
super(getExtURLs(dirs), null, factory);
this.dirs = dirs;
}[/code]他的父loader为空,而他的顶级父类是java.lang.ClassLoader而当传入的parent为null时,我们使用 ExtClassLoader load一个类时,系统会调用Bootstrap ClassLoader.
[code]
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
//先调用父loader来load.
c = parent.loadClass(name, false);
} else {
//调用Bootstrap ClassLoader来load
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}[/code]
而这里findBootstrapClass0也就是调用Bootstrap ClassLoader这个最核心的class loader来load class.

最终我们可以看到getSystemClassLoader() 返回的class loader就是AppClassLoader.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值