JAVA——ClassLoader详解

概述

之前的博客:Class装载过程讲解了一个类具体是怎么装载的,类装载分为加载、链接、初始化三个过程。Class装载对我们来说,最重要的是加载这个过程了。
java使用ClassLoader来加载一个类,他的主要工作是把二进制class文件加载到虚拟机里面去,并且返回一个Class对象,通过这个Class对象,我们可以获取一个类的方法和变量的元素。


ClassLoader类的介绍

classLoader是一个抽象类,要想使用它,我们必须要实现他的某些方法。他有几个非常重要的方法:

  • public loadClass(String name):给定一个类名,去加载这个类
  • protected final defineClass(String className,byte[] bytes,int off,int len),给定类名和class字节码流,把字节码加载到虚拟机中(这是真正做事情加载类的方法)
  • protected findClass(),查找一个类,这个是非常重要的一个方法,他实际上是一个抽象的方法,并不是指从虚拟机里去查找方法,而是定义了查找的逻辑。
  • findLoadedClass(String name):根据类名查找一个类是否已经加载到了虚拟机里面。

ClassLoader的分类

不同classLoader加载的类属于不同的类,ClassLoader分为四中,分别是:

  1. BootStrapClassLoader:启动类加载器,一般用来加载java中jre/lib/rt.jar包中的java类。
  2. ExtensionClassLoader:扩展类加载器,用来加载jre/lib/ext目录下的jar包
  3. AppClassLoader:应用类加载器,用来加载ClassPath下,也就是我们写的JAVA文件的类。
  4. 自定义类加载器。

    我们可以通过xxx.class.getClassLoader()来获取一个类加载器,并且可以通过classLoader.getParent()来获取某个类加载器的父类加载器。值得注意的是,我们的BoootStrapClassLoader是用C++写的,所以他并没有对应的JAVA对象,扩展类加载器通过getParent获取到的值是空。


双亲委托模式

JVM默认的类加载器是双亲委托模式,所谓的双亲委托模式是指:一个java类在通过类加载器加载的时候,他们首先会判断是否已经加载,如果没有加载,会先交给父类去加载,如果父类也没有,会交给父类的父类。如果父类无法加载,就会返回给子类加载。
因为一个类加载器在加载的时候,只会往上询问是否加载了这个类,所以双亲委托模式意味着,子类加载器是否加载了的类,父类加载器是不知道的。


双亲委托模式的突破

双亲委托模式可以通过传入子类加载器去获取一个类的Class,然后返回给父类加载器。
双亲委托模式还可以通过重新定义findClass方法,解决一个类只能由父加载器先加载的问题。

你可能感兴趣的:(JAVA进阶)