美文网首页饥人谷技术博客Java
[java]一文读懂ClassLoader

[java]一文读懂ClassLoader

作者: 小贾同学coding | 来源:发表于2020-03-19 23:44 被阅读0次

    1.什么是classLoader

     先来看一个概念,Class对象。什么是class对象呢?Java中用来表示运行时类型信息的对应类就是Class类,而Class对象就是Class所创建的一个实例,注意这里的Class类是实实在在的一个类,在java.lang包下。Class类的作用就是在运行时描述一个类的对象的类型和和类的信息,从而达到RTTI(RUNTIME TYPE IDENTIFICATION)运行时类型识别。java中的运行时类型识别有两种方式。一是编译时已确定的类型,例如

    List<Shape> shapeList = Arrays.asList(new Circle(), new Square(), new Triangle());
    for(Shape shape : shapeList) {
        shape.draw();
    }
    

    我们规定了shapeList的泛型,所以在运行期间当array中取出object对象时需要将对象转成Shape对象,需要做正确定检查,这里检查一个对象是否是Shape对象,就是在编译时已经指出的,需以Shape类型做正确性检查。
    二就是反射机制,这里就不做过多的描述,因为跑题了。
     而classLoader就是用来加载Class对象,将字节码形式的class转换成内存中的class对象。而字节码的本质就是一个byte[],classloader讲byte[]转换为class对象。

    2.classLoader的种类

    -BootstrapClassLoader(根加载器)

     负责加载 java核心类

    -ExtensionClassLoader ()

     拓展类加载 JAVA_HOME/lib/ext/下的类

    -AppClassLoader (系统类加载器)

     加载我们自己的编写的程序,使用的第三方jar包等 Classpath 环境变量里定义的路径中jar包和目录。

    3.classLoader的模式

    -双亲委派模式

    双亲委派模式

     当我们的程序在运行时,碰到一个未被加载的类怎么办呢?
     我们的程序会调用ClassLoader来加载这个类,那么这个类该由那种类加载呢?
     jvm的策略是由调用者的ClassLoader,即发现这个未被加载的类的类的ClassLoader,那么我们都知道自定义的和第三方的类是由AppClassLoader加载,那么假如这个未被加载的类是java核心类呢?是ext下的类呢?
     这里就引出了双亲委派模式,AppClassLoader发现一个未被加载的类那么并不会首先交由自己加载,而是向上交由自己的parent,即ExtensionClassLoader来加载,如果它无法加载,再去寻找classpath下的类并加载;同样的ExtensionClassLoader也会向上传递给BoostStrapClassLoader,如果它无法加载再去由自己加载。双亲委派模型保障了类加载的正确性。

    4.classLoader的重要方法

    -Class.forName

     Class.forName()的方法经常用来动态加载驱动类,如mysql;原理是对应的Driver类中有一个静态代码块,当class类被加载时会自动将驱动实例注册到驱动管理器中。

    class Driver {
      static {
        try {
           java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
           throw new RuntimeException("Can't register driver!");
        }
      }
      ...
    }
    

    &emsp;Class.forName()的特殊之处在于它可以指定类加载器进行加载,也就是允许了我们使用自定义的加载器进行加载。

    Class<?> forName(String name, boolean initialize, ClassLoader cl)
    
    -loadClass()

    加载目标类的入口

    -defineClass()

    将字节码转换为Class对象

    -findClass()

    搜寻字节码文件并调用defineClass()转换(通常由子类实现)

    至此,记录结束。
    这里引用一篇文章Class.forName和ClassLoader.loadClass
    本文借鉴,参考。额,部分照搬老大难的 Java ClassLoader

    相关文章

      网友评论

        本文标题:[java]一文读懂ClassLoader

        本文链接:https://www.haomeiwen.com/subject/tduryhtx.html