title: 类加载机制(六):getSystemClassLoader与Launcher
date: 2019-03-19 16:09:38
categories:
- Java虚拟机
tags: - 类加载机制
- Launcher类
- getSystemClassLoader
getSystemClassLoader
在前文类加载机制(四):解析ClassLoader,我们分析了ClassLoader
类的基本源码,了解了一个class
文件是如何被加载到内存中的,也知道了Java
应用默认是由系统类加载器加载的,那系统类加载器是由谁加载的、是如何加载的?我们通过贯穿ClassLoader
类的一个静态方法getSystemClassLoader
来对这些过程进行分析。
内部维护的字段
// The class loader for the system
// @GuardedBy("ClassLoader.class")
private static ClassLoader scl;
// Set to true once the system class loader has been set
// @GuardedBy("ClassLoader.class")
private static boolean sclSet;
在
ClassLoader
内部维护了两个与加载系统类加载器相关的静态变量,从注释中我们可以看出scl
就是用来接收系统类加载器的,而sclSet
则是一个布尔值,用来判断scl
是否为空的,关于系统类加载器基本都是操作这两个值的。
getSystemClassLoader
先来看看源码
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
}
调用
initSystemClassLoader()
,并且做了一些安全检查,直接返回系统类加载器scl
。
initSystemClassLoader
通过这个方法来初始化系统类加载器,只贴了主要代码。
private static synchronized void initSystemClassLoader() {
//若sclSet为真,则代表系统类加载已经被加载
if (!sclSet) {
if (scl != null)
throw new IllegalStateException("recursive invocation");
//创建一个Launcher,后文会讲
sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
Throwable oops = null;
//通过Launcher类,获取系统类加载器
scl = l.getClassLoader();
try {
//判断是否有自定义类加载器
scl = AccessController.doPrivileged(
new SystemClassLoaderAction(scl));
} catch (PrivilegedActionException pae) {
}
}
//设置sclSet为真
sclSet = true