类加载ClassLoader和双亲委派机制


类加载器的发生时间是在类加载过程的加载阶段发生的。
在这里插入图片描述

类加载器

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的代码不被使用者篡改了。
发布了60 篇原创文章 · 获赞 1 · 访问量 3335

猜你喜欢

转载自blog.csdn.net/qq_16438883/article/details/103553521