当前位置:首页 > Java

java类如何加载

2026-04-09 06:06:51Java

Java 类的加载机制

Java 类的加载是 Java 虚拟机(JVM)将类的字节码文件(.class)加载到内存中,并转换为运行时数据结构的过程。类的加载由类加载器(ClassLoader)完成,遵循双亲委派模型。

类加载的步骤

加载(Loading) 查找并加载类的二进制数据(.class 文件),生成一个代表该类的 Class 对象。类加载器可以从文件系统、网络或其他来源加载类。

验证(Verification) 确保加载的类符合 JVM 规范,防止恶意代码破坏 JVM。验证内容包括文件格式、元数据、字节码和符号引用等。

准备(Preparation) 为类的静态变量分配内存并设置默认初始值(零值)。例如,static int a 的默认值为 0,而非代码中显式赋予的值。

解析(Resolution) 将符号引用转换为直接引用。符号引用是类、方法或字段的名称,直接引用是具体的内存地址或偏移量。

java类如何加载

初始化(Initialization) 执行类的静态代码块(static {})和静态变量的显式赋值。这是类加载的最后一步,确保类完全准备好使用。

类加载器层次结构

Bootstrap ClassLoader 加载 Java 核心类库(如 java.lang.*),由 JVM 实现,通常用本地代码编写,不继承 java.lang.ClassLoader

Extension ClassLoader 加载扩展库(JAVA_HOME/lib/ext 目录下的类),是 sun.misc.Launcher$ExtClassLoader 的实例。

java类如何加载

Application ClassLoader 加载应用程序类路径(ClassPath)下的类,是 sun.misc.Launcher$AppClassLoader 的实例。

自定义 ClassLoader 用户可以通过继承 ClassLoader 类实现自定义类加载器,用于特定场景(如热部署、模块化加载)。

双亲委派模型

类加载器在加载类时,先委托父类加载器尝试加载。只有父类加载器无法加载时,子类加载器才会尝试加载。这种机制保证了类的唯一性和安全性,避免重复加载和核心类被篡改。

代码示例:自定义类加载器

public class CustomClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = loadClassData(name); // 从自定义路径加载字节码
        if (classData == null) {
            throw new ClassNotFoundException();
        }
        return defineClass(name, classData, 0, classData.length);
    }

    private byte[] loadClassData(String className) {
        // 实现从文件或网络加载字节码的逻辑
        return null;
    }
}

类加载的触发条件

以下情况会触发类的初始化:

  • 创建类的实例(new 关键字)。
  • 访问类的静态变量或静态方法。
  • 使用反射(Class.forName())。
  • 初始化子类时,父类会先初始化。
  • JVM 启动时指定的主类(包含 main 方法的类)。

注意事项

  • 类加载是懒加载的,只有在首次使用时才会初始化。
  • 静态变量的赋值和静态代码块的执行顺序与代码中的声明顺序一致。
  • 打破双亲委派模型需谨慎,可能导致类冲突或安全问题。

标签: 加载java
分享给朋友:

相关文章

java如何创建数组

java如何创建数组

创建数组的基本方法 在Java中,数组是固定大小的同类型元素集合。创建数组需要声明数组类型并初始化。 声明数组 语法格式为 数据类型[] 数组名 或 数据类型 数组名[]: int[] arr1;…

java如何创建包

java如何创建包

创建Java包的步骤 在Java中,包(package)用于组织和管理类文件,避免命名冲突。以下是创建Java包的详细方法: 定义包名 在Java源文件的开头使用package关键字声明包名。包名…

jquery页面加载

jquery页面加载

jQuery 页面加载事件 在 jQuery 中,页面加载事件通常通过 $(document).ready() 或简写的 $() 来实现。这种方式确保代码在 DOM 完全加载后执行,但无需等待图片等资…

eclipse如何创建java

eclipse如何创建java

在Eclipse中创建Java项目 打开Eclipse后,选择菜单栏中的"File" -> "New" -> "Java Project"。在弹出的对话框中输入项目名称,确保"Use de…

js实现图片的懒加载

js实现图片的懒加载

实现图片懒加载的基本原理 懒加载的核心思想是延迟加载非视口内的图片,当用户滚动页面时再动态加载即将进入视口的图片资源。这能显著减少页面初始加载时的网络请求和带宽消耗。 Intersection Ob…

vue实现异步加载

vue实现异步加载

Vue 异步加载的实现方法 在 Vue 中实现异步加载可以通过多种方式完成,包括动态导入、路由懒加载和异步组件等。以下是几种常见的实现方法: 动态导入与异步组件 使用 Vue 的 defineAsy…