0

0

在Java里类是如何被加载的_Java类加载流程解析

P粉602998670

P粉602998670

发布时间:2026-02-03 12:38:55

|

587人浏览过

|

来源于php中文网

原创

Java类加载按需触发、分阶段进行,仅在七种主动使用情形下初始化并倒逼加载链接;遵循双亲委派模型确保核心类如String不被污染;loadClass负责委派,defineClass真正转换字节码为Class对象。

在java里类是如何被加载的_java类加载流程解析

Java 类的加载不是一次性完成的,而是按需触发、分阶段进行的——类只有在首次主动使用时才开始加载,且整个过程由类加载器(ClassLoader)协作完成,不满足“主动使用”条件时,即使写了 Class.forName("Xxx") 也可能跳过初始化。

类加载的触发时机:什么算“主动使用”

只有以下七种情况才会触发类的初始化(即执行 方法),进而倒逼加载、链接(验证、准备、解析):

  • 创建该类的实例(new Xxx()
  • 调用该类的静态方法(Xxx.staticMethod()
  • 访问该类的静态字段(Xxx.STATIC_FIELD),但**不包括被 final 修饰的编译期常量**(如 public static final int VAL = 123;
  • 反射调用(Class.forName("Xxx"),注意:带布尔参数的 Class.forName(name, false, loader) 可跳过初始化)
  • 子类初始化时,若父类未初始化,则先触发父类初始化
  • 启动类(main 方法所在类)被 JVM 启动时
  • 使用 JDK 7+ 的动态语言支持(如 invokedynamic)且对应 CallSite 初始化时

常见误区:MyClass.class 字面量、数组声明 MyClass[] arr、继承关系检查、静态字段的引用但值为编译期常量——这些都不会触发初始化,自然也不强制加载。

双亲委派模型:为什么 String 不会被自定义类加载器污染

类加载器不是孤立工作的,而是按“启动类加载器 → 扩展类加载器 → 应用类加载器 → 自定义类加载器”的链式结构向上委托。核心逻辑在 ClassLoader.loadClass(String name) 中体现:

立即学习Java免费学习笔记(深入)”;

  • 先检查该类是否已加载(findLoadedClass(name)
  • 若未加载,且存在父加载器,则调用 parent.loadClass(name)
  • 父加载器返回 null 或抛出 ClassNotFoundException 后,才调用本加载器的 findClass(name)

这意味着 java.lang.String 永远由启动类加载器加载,即使你在应用类加载器里重写了一个同名类,JVM 也会拒绝加载——因为委托链顶端已提供合法版本。绕过双亲委派(如重写 loadClass 而不调用父类)需谨慎,容易破坏类型隔离和安全边界。

DeepBrain
DeepBrain

AI视频生成工具,ChatGPT +生成式视频AI =你可以制作伟大的视频!

下载

loadClass vs defineClass:谁真正把字节码变成 Class 对象

loadClass 是入口方法,负责调度与委派;真正将二进制字节流转换为 JVM 内部 Class 实例的是 defineClass

  • loadClass("com.example.Foo"):可能从磁盘读取、网络拉取、或生成字节码,最终调用 defineClass
  • defineClass("com.example.Foo", byte[], offset, len):校验字节码格式、分配内存、生成运行时常量池等,返回 Class> 对象(此时尚未初始化)
  • 后续若需初始化,必须显式调用 resolveClass(Class) 或等待首次主动使用

自定义类加载器时,绝不能直接覆盖 loadClass 来跳过委派,而应重写 findClass 并在其中调用 defineClass。否则会破坏双亲委派,引发 NoClassDefFoundErrorLinkageError

常见加载失败错误:从 ClassNotFoundExceptionNoClassDefFoundError

二者表面相似,根源完全不同:

  • ClassNotFoundException:在运行期尝试通过类名加载类时,**类加载器找不到对应的 class 文件或字节码源**(如 Class.forName("Missing") 失败)
  • NoClassDefFoundError:类在编译期存在,但在运行期**加载或链接阶段失败后,再次引用该类时抛出**(典型场景:A 类引用 B 类,B 类静态块抛异常导致初始化失败,之后任何对 B 的访问都触发此错误)
  • LinkageError(如 IncompatibleClassChangeError):同一类被不同类加载器重复定义,或签名不兼容(如接口变抽象类)

排查时优先看堆中是 Exception 还是 Error,再结合类加载日志(加 -verbose:class)确认是否真的加载过、由哪个加载器加载、是否发生过链接失败。

类加载流程的真正复杂点不在“怎么走”,而在“什么时候走”和“被谁走”——同一个类名,不同类加载器实例加载出来就是不同的类型,哪怕字节码完全一致;而初始化时机的微妙差异,又直接影响静态字段赋值顺序和单例行为。这些细节不会报错,但会让问题藏得极深。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

543

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

238

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

519

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1505

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1505

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1505

2023.10.24

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

268

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

305

2023.10.25

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

0

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.2万人学习

C# 教程
C# 教程

共94课时 | 8.4万人学习

Java 教程
Java 教程

共578课时 | 56.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号