likes
comments
collection
share

Java 类加载器详解

作者站长头像
站长
· 阅读数 58

大家好,我是老谭说架构,今天要跟大家分享下Java类加载器的原理,Java 类加载器是Java 虚拟机 (JVM)的重要组成部分。它们用于加载类和接口。虽然类加载器是 JVM 不可或缺的一部分,它们对于 Java 的内部工作非常重要,但作为一名 Java 开发人员,您在日常工作中不太可能需要创建自定义类加载器。自定义类加载器的实际应用是,例如,如果您想创建将在 Tomcat 等容器上执行的应用程序。Tomcat 所做的是为每个 Web 应用程序创建一个类加载器(以便它可以稍后卸载 Web 应用程序并释放内存)。

本文旨在解释类加载器的工作原理并列出 Java 类加载器的关键组件。您可能会在下一次 Java 工作面试中遇到有关类加载器的问题。

什么是Java ClassLoader

我们知道 Java 程序在 Java 虚拟机 (JVM)上运行。当我们编译 Java 类时,它会转换为独立于平台和机器的字节码。编译后的类存储为 .class 文件。当��们尝试使用某个类时,Java ClassLoader 会将该类加载到内存中。当在已运行的类中按名称引用类时,类将被引入 Java 环境中。一旦第一个类运行,类加载器就会尝试加载类。运行第一个类通常是通过声明和使用静态 main() 方法来完成的。

Java 类加载器详解 类加载器的层次结构

Java 类加载器的类型

  1. Bootstrap 类加载器 - 它加载 JDK 内部类,通常加载 rt.jar 和其他核心类,例如 java.lang.* 包类
  2. 扩展类加载器 ——它从 JDK 扩展目录(通常是 JRE 的 lib/ext 目录)加载类。
  3. 系统类加载器 ——从系统类路径加载类,可以在调用程序时使用 -cp 或 -classpath 命令行选项进行设置。

何时以及如何加载类

什么时候加载类?有两种情况:

  1. 当执行新的字节码时(例如,  MyClass mc  = new  MyClass()  😉
  2. 当字节码对某个类进行静态引用时(例如,  System.out 。**

类加载器是分层的。第一个类是借助类中声明的静态 main() 方法专门加载的。所有后续加载的类均由已加载并正在运行的类加载。

进一步的类加载器在加载类时遵循以下规则:

  1. 检查该类是否已被加载。
  2. 如果没有加载,则请求父类加载器加载该类。
  3. 如果父类加载器无法加载类,则尝试在此类加载器中加载它。

静态与动态类加载

类是使用 Java 的“new”运算符静态加载的。动态加载是一种在运行时使用 Class.forName() 以编程方式调用类加载器函数的技术

loadClass 和 Class.forName 之间的区别

loadClass只加载类,不初始化对象,而Class.forName加载后初始化对象。例如,如果您使用ClassLoader.loadClass加载 JDBC 驱动程序,它将不会注册,您将无法使用 JDBC

java.lang.Class.forName   (String className) 方法返回与给定字符串名称的类或接口关联的 Class 对象。如果未找到该类,则此方法抛出 ClassNotFoundException

以下示例演示了 Class.forName 的用法

package net.javatutorial;

import java.lang.reflect.Method;

public class ClassForNameExample {

    public static void main(String[] args) {
        try {
            Class<?> c = Class.forName("java.awt.Point");
            System.out.println("name = " + c.getName());
            System.out.println("package = " + c.getPackage());
            Method[] methods = c.getDeclaredMethods();
            System.out.println("----- Class methods ---------------");
            for (Method method : methods) {
                System.out.println(method.getName());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

java.awt.Point 类已加载。然后我们打印类名、包和该类所有可用方法的名称。这是在 Java 8 中执行程序的结果:

name = java.awt.Point
package = package java.awt, Java Platform API Specification, version 1.8
----- Class methods ---------------
equals
toString
getLocation
getX
getY
setLocation
setLocation
setLocation
move
translate
转载自:https://juejin.cn/post/7388281982986010659
评论
请登录