Java类加载机制

2024-06-12 10:28

1、Java程序的启动

Java程序的启动并运行的过程

由图可见:

Java 类加载机制是 Java 运行时的核心组成部分、负责在程序运行过程中动态加载和连接类文件,并将其转换为可执行代码。

  • 实现动态加载:Java 类加载机制允许程序在运行时根据需要动态地加载类文件。这种能力使得开发人员可以根据实际需求来加载所需的类,而不需要一次性加载所有的类。这对于大型应用程序和框架来说特别有用,因为它们可能包含大量的类,但只有在需要时才会加载。

  • 解决依赖关系:Java 类加载机制可以解决类之间的依赖关系。当一个类引用另一个类时,如果被引用的类还未被加载,类加载机制会自动触发对被引用类的加载。这种机制确保了类的正确顺序加载,避免了由于依赖关系引起的编译错误或运行时错误。

  • 实现类的隔离性:Java 类加载器通过不同的命名空间实现了类的隔离性。每个类加载器都有自己的命名空间,同一个类可以被不同的类加载器加载多次,每次都会生成独立的类对象。这种隔离性使得不同的模块或应用可以使用不同的类版本,避免了类之间的冲突。

  • 支持动态代理和反射:Java 类加载机制为动态代理和反射提供了基础。通过类加载器,我们可以在运行时动态地生成代理类,并且可以在运行时获取和操作类的字段、方法等信息。这种能力使得 Java 在面向对象编程和框架设计方面更加灵活和强大。

  • 实现安全性和权限控制:Java 类加载机制可以实现安全性和权限控制。它可以限制某些类只能由特定的类加载器加载,从而控制类的访问权限。这对于保护系统的安全性和防止恶意代码的执行至关重要。

类加载器

启动类加载器(Bootstrap Class Loader)

启动类加载器(Bootstrap Class Loader)是 Java 类加载器中的最顶层的一个加载器,它负责加载 Java 运行时核心类库和其他被 JVM 所信任的重要类。

  • 加载核心类库:启动类加载器负责加载 Java 运行时所需的核心类库,包括Java标准库(rt.jar)和扩展库(ext目录下的jar文件)。这些类库包含了 Java 语言的基本类,如Object、String等,以及Java运行时的核心类,如Class、ClassLoader等。

  • 无法直接获取:启动类加载器是 JVM 实现的一部分,通常由系统或者虚拟机实现语言编写,无法在Java代码中直接获取到。它是 JVM 的一部分,存在于JVM内核中。

  • 实现为本地代码:由于启动类加载器是 JVM 实现的一部分,因此它的实现通常是用本地代码(C/C++)编写的。这样可以保证加载器的安全性和效率。

  • 非Java类加载器:启动类加载器不是一个普通的Java类加载器,它不继承自java.lang.ClassLoader类(Java中所有类加载器的基类),而是由JVM实现为特殊的逻辑加载器。

  • 独立于Java应用:启动类加载器是在 JVM 启动过程中被创建的,它独立于任何Java应用程序。它的主要目的是加载核心类库,为后续的类加载器提供基础。

  • 位于引导类路径上:启动类加载器从一个特定的位置加载类,该位置被称为引导类路径(Bootstrap Classpath)。引导类路径通常是 JVM 实现的一部分,并且会根据不同的 JVM 实现而有所不同。

  • 无法自定义:由于启动类加载器是 JVM 的一部分,因此无法对其进行自定义或替换。它负责加载 Java 运行时的基础类库,保证了Java程序运行的稳定性和安全性。

扩展类加载器(Extension Class Loader)

扩展类加载器(Extension Class Loader)是 Java 类加载器中的一种,它是属于标准的系统类加载器的一部分。扩展类加载器用于加载 Java 虚拟机扩展目录(Java Extension Directory)中的类库。

  • 加载扩展目录:扩展类加载器负责加载 Java 虚拟机的扩展目录(Java Extension Directory),该目录的位置由系统属性 java.ext.dirs 指定。默认情况下,扩展目录位于 <JRE_HOME>/lib/ext 目录下。

  • 扩展目录的作用:扩展目录是用于存放 Java 虚拟机的扩展类库或第三方库的目录。它提供了一种在 Java 平台上安装额外功能的机制,使得开发人员可以通过简单地将 JAR 文件放置到扩展目录中来扩展 Java 的功能。

  • 从父类加载器继承:扩展类加载器是标准的系统类加载器的一个实例,它从父类加载器(一般是启动类加载器)继承加载类的能力。这意味着当扩展类加载器无法加载一个类时,它会委派给父类加载器来尝试加载。

  • 加载扩展类库:扩展类加载器主要用于加载扩展目录中的类库。扩展目录中的类库是一些提供额外功能或扩展 Java API 的类库,它们通常以 JAR 文件的形式存在。

  • 独立于应用程序:扩展类加载器是独立于应用程序的,它是 JVM 内置的一个类加载器,负责加载系统级别的类库。它和应用程序的类加载器(如应用类加载器)是相互独立的。

  • 可以自定义扩展目录:通过修改系统属性 java.ext.dirs,我们可以自定义扩展目录的位置。这样,我们可以将一些额外的类库放置到自定义的扩展目录中,并由扩展类加载器加载。

  • 实现为纯Java类:扩展类加载器的实现是一个普通的 Java 类,它继承自 java.net.URLClassLoader。这使得我们可以通过 Java 代码来获取扩展类加载器实例,并与其交互。

应用程序类加载器(Application Class Loader)

应用程序类加载器(Application Class Loader),也称为系统类加载器(System Class Loader),是 Java 类加载器中的一种。它负责加载应用程序的类和资源文件。

  • 加载应用程序类:应用程序类加载器是负责加载应用程序的类的主要类加载器。它从指定的类路径(Classpath)中加载类文件,包括应用程序的源代码编译后生成的字节码文件。

  • 类路径的设置:类路径是指用于查找类文件的路径列表。在运行 Java 程序时,我们可以通过命令行参数 -classpath 或简写的 -cp 来设置类路径。类路径可以包含目录和 JAR 文件。

  • 与系统类加载器关联:应用程序类加载器是系统类加载器的实例,它继承了系统类加载器的行为和能力。系统类加载器是ClassLoader类的子类,Java虚拟机在启动时自动创建了一个系统类加载器,并将其指定给应用程序类加载器。

  • 搜索顺序:应用程序类加载器按照特定的搜索顺序加载类。首先,它会尝试使用自己的类路径加载类文件。如果找不到,则会委派给父类加载器,依次往上搜索,直到达到顶层的启动类加载器为止。这种委派模型称为双亲委派模型。

  • 加载应用程序资源:除了加载类文件,应用程序类加载器还负责加载应用程序的资源文件。资源文件可以是文本文件、配置文件、图片等应用程序所需的其他非类文件。通过应用程序类加载器,我们可以使用 getResource()getResourceAsStream() 方法来获取应用程序的资源。

  • 可以自定义类加载器:虽然应用程序类加载器是由Java虚拟机在运行时自动创建的,但我们也可以通过编写自定义的类加载器来替换或扩展它的功能。自定义类加载器可以用于实现特定的类加载策略,如从数据库、网络或非标准路径加载类。

  • 独立于应用程序:应用程序类加载器是与特定的应用程序相关联的,它负责加载应用程序的类和资源。每个应用程序都有自己独立的应用程序类加载器,不同的应用程序之间相互独立。

如下图:

类加载器的触发动作是由以下方式:

1、Class.forName

2、ClassLoader.loadClass

3、JVM触发

过程如下:

相关新闻
热点
视频
投票
查看结果
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量:

© 2025 个人网站 版权所有

备案号:苏ICP备2024108837号

苏公网安备32011302322151号