Java ClassLoader

Java ClassLoader

Java ClassLoaderJava运行时环境 的一部分,它动态地将Java类加载到 Java虚拟机中。 因为有了类加载器,Java运行时系统不需要了解文件和文件系统。Java类并不是一下子就加载到内存中,而是在应用程序需要时才加载。这时, JRE 会调用 Java ClassLoader ,这些ClassLoader会动态地将类加载到内存中。

Java中ClassLoaders的类型

不是所有的类都由一个ClassLoader加载。根据类的类型和类的路径,决定加载该特定类的ClassLoader。要知道加载一个类的ClassLoader,可以使用 _ getClassLoader()_ 方法。所有的类都是根据它们的名字来加载的,如果没有找到这些类,就会返回 NoClassDefFoundErrorClassNotFoundException。 一个Java Classloader有 三种类型。

  1. BootStrap ClassLoader: Bootstrap Classloader是一个机器代码,当JVM调用它时,它就会启动操作。它不是一个java类。它的工作是加载第一个纯Java ClassLoader。Bootstrap ClassLoader从 _ rt.jar_ 的位置加载类。Bootstrap ClassLoader没有任何父级ClassLoader。它也被称为 原始的ClassLoader。
  2. Extension ClassLoader: Extension ClassLoader是Bootstrap ClassLoader的子代,从相应的JDK扩展库中加载核心java类的扩展。它从 _ jre/lib/ext_ 目录或由系统属性 _ java.ext.dirs_ 指向的任何其他目录中加载文件 _ 。_
  3. 系统类加载器: 应用程序类加载器也被称为系统类加载器。它加载在环境变量 _ CLASSPATH、-classpath或-cp命令行选项_ 中找到的应用程序类型的类。应用程序类加载器是扩展类加载器的一个子类。

注意 :ClassLoader委托层次模型总是按照Application ClassLoader->Extension ClassLoader->Bootstrap ClassLoader的顺序运行。Bootstrap ClassLoader总是被赋予较高的优先级,接下来是Extension ClassLoader,然后是Application ClassLoader。

Java ClassLoader

Java ClassLoader的功能原则

功能原则是Java ClassLoader工作所依据的 一组规则 或特征。有 三个功能原则 ,它们是。

  1. 委托模型 :Java虚拟机和Java ClassLoader使用一种叫做 委托层次算法 的算法,将类加载到Java文件中。ClassLoader根据委托模型给出的一组操作来工作。它们是
  • ClassLoader总是遵循 Delegation Hierarchy原则。
  • 每当JVM遇到一个类,它就会检查该类是否已经被加载。
  • 如果该类已经被加载到方法区,那么JVM就会继续执行。
  • 如果该类不在方法区,那么JVM会要求Java ClassLoader子系统加载该特定的类,然后ClassLoader子系统将控制权移交给 Application ClassLoader。
  • Application ClassLoader然后将请求委托给Extension ClassLoader, Extension ClassLoader 又将请求委托给 Bootstrap ClassLoader。
  • Bootstrap ClassLoader将在Bootstrap classpath(JDK/JRE/LIB)中搜索。如果该类是可用的,那么它就会被加载,如果不是,请求会被委托给Extension ClassLoader。
  • Extension ClassLoader在Extension Classpath(JDK/JRE/LIB/EXT)中搜索该类。如果该类是可用的,那么它将被加载,如果不是,请求将被委托给应用程序ClassLoader。
  • Application ClassLoader在Application Classpath中搜索该类。如果该类是可用的,那么它就被加载,如果不是,就会产生一个 ClassNotFoundException 异常。
    1. 可见性原则可见性原则 指出,由父类加载器加载的类对子类加载器是可见的,但由子类加载器加载的类对父类加载器是不可见的。假设一个GEEKS.class被Extension ClassLoader加载,那么该类只对Extension ClassLoader和Application ClassLoader可见,而对Bootstrap ClassLoader不可见。如果再次尝试使用Bootstrap ClassLoader加载该类,就会出现 _ java.lang.ClassNotFoundException异常。_
    2. 唯一性属性唯一性属性 确保类是唯一的,没有重复的类。这也确保了由父类加载器加载的类不会被子类加载器加载。如果父类加载器不能够找到该类,那么只有当前的实例才会自己尝试这样做。

Java.lang.ClassLoader的方法

在JVM对类提出请求后,为了加载一个类,需要遵循几个步骤。类是按照委托模式加载的,但有几个重要的方法或函数在加载类时起着至关重要的作用。

  1. loadClass(String name, boolean resolve) : 这个方法用来加载JVM引用的类。它将类的名称作为一个参数。这个方法的类型是loadClass(String, boolean)。
  2. defineClass() : defineClass()方法是一个 最终 方法,不能被重写。这个方法用来定义一个字节数组作为一个类的实例。如果该类是无效的,它将抛出 ClassFormatError。
  3. findClass(String name) : 这个方法用来查找一个指定的类。这个方法只找到但不加载该类。
  4. findLoadedClass(String name) : 该方法用于验证JVM引用的类是否已经被加载。
  5. Class.forName(String name, boolean initialize, ClassLoader loader) : 该方法用于加载类以及初始化类。这个方法还提供了选择任何一个ClassLoader的选项。如果ClassLoader参数为NULL,则使用Bootstrap ClassLoader。

例子: 下面的代码在类被加载之前被执行。

protected synchronized Class<?>
loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    Class c = findLoadedClass(name);
    try {
        if (c == NULL) {
            if (parent != NULL) {
                c = parent.loadClass(name, false);
            }
            else {
                c = findBootstrapClass0(name);
            }
        }
        catch (ClassNotFoundException e)
        {
            System.out.println(e);
        }
    }
}

注意 :如果一个类已经被加载了,它将返回该类。否则,它将寻找新类的工作委托给父类加载器。如果父类加载器没有找到该类, loadClass() 会调用 findClass() 方法来寻找并加载该类。如果父类加载 没有找到该类,findClass( ) 方法会在当前的 ClassLoader 中搜索该类 。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程