类加载器的发生时间是在类加载过程的加载阶段发生的。

类加载器
1.Bootstrap Class Loader会加载rt.jar下面的C++代码(启动类加载器)
2.Extension Class Loader会加载ext/*.jar下面的代码(扩展类加载器)
3.System Class Loader会加载用户自定义的代码(应用程序类加载器)
用程序打印类加载器
package all;
public class ClassLoaderTest {
public static void main(String[] args) {
System.out.println("根加载器:"+new ClassLoaderTest().getClass().getClassLoader().getParent().getParent());
System.out.println("扩展类加载器:"+new ClassLoaderTest().getClass().getClassLoader().getParent());
System.out.println("用户类加载器:"+new ClassLoaderTest().getClass().getClassLoader());
System.out.println("=====================================");
System.out.println(new Object().getClass().getClassLoader());
}
}
类加载器源码
protected Class<?> loadClass(Stringname,boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先从jvm缓存查找该类
Class c = findLoadedClass(name); // (1)
if (c ==null) {
longt0 = System.nanoTime();
try { //然后委托给父类加载器进行加载
if (parent !=null) {
c = parent.loadClass(name,false); (2)
} else { //如果父类加载器为null,则委托给BootStrap加载器加载
c = findBootstrapClassOrNull(name); (3)
}
} catch (ClassNotFoundExceptione) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c ==null) {
// 若仍然没有找到则调用findclass查找
// to find the class.
longt1 = System.nanoTime();
c = findClass(name); (4)
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 -t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c); //(5)
}
returnc;
}
}
- 1.当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
- 2.当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
- 3.当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
双亲委派机制
双亲委派机制得工作过程:
1.类加载器收到类加载的请求;
2.把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器;
3.启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载。
4.重复步骤三
沙箱安全机制
主要是保证代码的安全证,保证jdk的代码不被使用者篡改了。