专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 一文告诉你Java类加载器有哪些

一文告诉你Java类加载器有哪些

更新时间:2022-07-18 12:44:31 来源:赢咖4 浏览1718次

Java 类加载器是Java 运行时环境的一部分,它可以将 Java 类动态加载到Java 虚拟机中。由于类加载器,Java 运行时系统不需要了解文件和文件系统。

Java 类不会一次全部加载到内存中,而是在应用程序需要时加载。此时,JRE调用Java ClassLoader,这些 ClassLoader 将类动态加载到内存中。

Java 中的类加载器类型

并非所有类都由单个 ClassLoader 加载。根据类的类型和类的路径,决定加载该特定类的 ClassLoader。要了解加载类的 ClassLoader,请使用getClassLoader()方法。所有类都根据它们的名称加载,如果找不到这些类中的任何一个,则返回NoClassDefFoundError或ClassNotFoundException。

Java 类加载器分为三种类型:

BootStrap ClassLoader:Bootstrap ClassLoader是一个机器代码,它在 JVM 调用它时启动操作。它不是一个java类。它的工作是加载第一个纯Java ClassLoader。Bootstrap ClassLoader 从rt.jar位置加载类。Bootstrap ClassLoader 没有任何父 ClassLoader。它也被称为Primodial ClassLoader。

Extension ClassLoader: Extension ClassLoader 是 Bootstrap ClassLoader 的子类,从各自的 JDK Extension 库中加载核心 java 类的扩展。它从jre/lib/ext目录或系统属性java.ext.dirs指向的任何其他目录加载文件。

系统类加载器:应用程序类加载器也称为系统类加载器。它加载在环境变量CLASSPATH、-classpath 或 -cp 命令行选项中找到的应用程序类型类。Application ClassLoader 是 Extension ClassLoader 的子类。

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

Java ClassLoader 的功能原理

功能原则是Java 类加载器工作的一组规则或特性。功能的三个原则,它们是:

委托模型:Java 虚拟机和 Java 类加载器使用一种称为委托层次算法的算法将类加载到 Java 文件中。

ClassLoader 基于委托模型给出的一组操作工作。他们是:

ClassLoader 始终遵循委托层次原则。

每当 JVM 遇到一个类时,它都会检查该类是否已经加载。

如果该类已经加载到方法区域中,则 JVM 继续执行。

如果该类不在方法区域中,则 JVM 要求 Java ClassLoader Sub-System 加载该特定类,然后 ClassLoader 子系统将控制权移交给Application ClassLoader。

然后,Application ClassLoader 将请求委托给 Extension ClassLoader,而Extension ClassLoader又将请求委托给Bootstrap ClassLoader。

Bootstrap ClassLoader 将在 Bootstrap 类路径(JDK/JRE/LIB)中搜索。如果类可用,则加载它,否则将请求委托给 Extension ClassLoader。

Extension ClassLoader 在 Extension Classpath(JDK/JRE/LIB/EXT) 中搜索类。如果类可用,则加载它,否则将请求委托给 Application ClassLoader。

Application ClassLoader 在 Application Classpath 中搜索类。如果该类可用,则加载它,如果不可用,则生成ClassNotFoundException异常。

可见性原则:可见性原则指出,由父类加载器加载的类对子类加载器可见,但由子类加载器加载的类对父类加载器不可见。假设一个类 GEEKS.class 已被 Extension ClassLoader 加载,那么该类仅对 Extension ClassLoader 和 Application ClassLoader 可见,而对 Bootstrap ClassLoader 不可见。如果再次尝试使用 Bootstrap ClassLoader 加载该类,则会给出异常java.lang.ClassNotFoundException。

唯一性属性:唯一性属性确保类是唯一的并且没有类的重复。这也确保了父类加载器加载的类不会被子类加载器加载。如果父类加载器无法找到该类,那么只有当前实例会尝试自己这样做。

Java.lang.ClassLoader 的方法

在 JVM 请求类之后,需要执行几个步骤来加载类。类是根据委托模型加载的,但有一些重要的方法或函数在加载类中起着至关重要的作用。

loadClass(String name, boolean resolve):该方法用于加载JVM引用的类。它将类的名称作为参数。这是 loadClass(String, boolean) 类型。

defineClass():defineClass() 方法是最终方法,不能被覆盖。此方法用于将字节数组定义为类的实例。如果类无效,则抛出ClassFormatError。

findClass(String name):此方法用于查找指定的类。此方法只查找但不加载类。

findLoadedClass(String name):该方法用于验证 JVM 引用的 Class 之前是否已加载。

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()来查找并加载该类。如果父ClassLoader没有找到该类, findClass()方法会在当前ClassLoader中搜索该类。如果大家想了解更多相关知识,不妨来关注一下赢咖4的Java赢咖4在线学习,里面的课程内容从入门到精通,很适合零基础的小伙伴学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>