如果不在构造函数中特别指定parent,用户自定义的类加载器的parent都是system classloader,可以通过getParent( ) 方法获取。
1. Class.forName( name )
public
static
Class
<?>
forName(String className)
throws ClassNotFoundException ... {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}
throws ClassNotFoundException ... {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}
/** */
/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
static
ClassLoader getCallerClassLoader()
...
{
// NOTE use of more generic Reflection.getCallerClass()
Class caller = Reflection.getCallerClass(3);
// This can be null if the VM is requesting it
if (caller == null) ...{
return null;
}
// Circumvent security check since this is package-private
return caller.getClassLoader0();
}
// NOTE use of more generic Reflection.getCallerClass()
Class caller = Reflection.getCallerClass(3);
// This can be null if the VM is requesting it
if (caller == null) ...{
return null;
}
// Circumvent security check since this is package-private
return caller.getClassLoader0();
}
Class.forName是使用调用者的类加载器来加载指定类的。也可以在另外一种形式的调用中指定类加载器。
2. ClassLoader.loadClass( name )
使用指定的类加载器加载类,与调用者的类加载器无关。
3. Thread.currentThread().getContextClassLoader()
获取当前线程上下文的ClassLoader,如果在线程创建后,不做任何设置,当前线程上下文的ClassLoader就是System ClassLoader。在线程创建后,可以设置使用自定义的类加载器。
与Class.forName很相似,不过,如果线程创建者的加载器与当前线程上下文的ClassLoader不一样时,两者是有区别的。当前线程上下文的ClassLoader在编写框架类软件时好用,而Class.forName在编写业务逻辑时就足够了。