[b]1. ContextClassLoader 线程上下文类加载器[/b]
线程上下文 ClassLoader 由线程创建者提供,供运行于该线程的代码加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader。
原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器,下面的代码片段是截至 sun.misc.Launcher 类,此类由“启动类加载器”加载
[b]2. static 静态块的初始化[/b]
static 静态块只有在使用 new 或 Class.forName(className) 时才会被初始化,并且只执行1次
Class.forName() 方法内部是通过 jni 调用本地代码实现的 Class.forName0(className, true, ClassLoader.getCallerClassLoader())
new 与 Class.forName(className) 的区别在于,使用 new 必须显示的 import 类,否则就无法编译通过。而Class.forName是在运行时查找与加载。
线程上下文 ClassLoader 由线程创建者提供,供运行于该线程的代码加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader。
Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(ClassLoader);
原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器,下面的代码片段是截至 sun.misc.Launcher 类,此类由“启动类加载器”加载
private static Launcher launcher = new Launcher();
public static Launcher getLauncher() {
return launcher;
}
public Launcher() {
//扩展类加载器
ClassLoader extcl;
try {
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
"Could not create extension class loader");
}
//系统类加载器
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader");
}
//设置原始线程的上下文ClassLoader为系统类加载器
Thread.currentThread().setContextClassLoader(loader);
...
}
[b]2. static 静态块的初始化[/b]
static 静态块只有在使用 new 或 Class.forName(className) 时才会被初始化,并且只执行1次
Class.forName() 方法内部是通过 jni 调用本地代码实现的 Class.forName0(className, true, ClassLoader.getCallerClassLoader())
/**
* @param name 类名
* @param initialize 是否必须初始化类,如果为false初始化将在第1次实例化类时执行,只执行1次
* @param loader 用于加载类的类加载器
* @return
* @throws ClassNotFoundException
*/
private static native Class forName0(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException;
new 与 Class.forName(className) 的区别在于,使用 new 必须显示的 import 类,否则就无法编译通过。而Class.forName是在运行时查找与加载。