Java中Class.forName和ClassLoader.loadClass的区别_类初始化时机的差异

夏芳小哥_6726

夏芳小哥_6726

2026-03-21

350人浏览

原创

Class.forName会触发类初始化而loadClass不会,导致静态代码块和静态字段是否执行;前者用于JDBC驱动注册等需立即初始化场景,后者适用于延迟加载但易引发初始化异常。

java中class.forname和classloader.loadclass的区别_类初始化时机的差异

Class.forName 会触发类初始化,loadClass 不会

这是最核心的差异,直接决定静态代码块和静态字段是否执行。很多线上问题就卡在这儿:比如 JDBC 驱动注册失败、Spring Bean 初始化顺序异常、或单元测试里 static final 字段值为 null。

原因在于 Class.forName(String) 默认调用的是 Class.forName(String, boolean, ClassLoader) 的重载版本,第二个参数为 true,即强制初始化;而 ClassLoader.loadClass(String) 的规范定义明确要求「不初始化」,只完成加载和链接阶段。

  • Class.forName("com.example.MyUtil") → 执行 static {} 块,赋值 static final int VERSION = 1;
  • MyUtil.class.getClassLoader().loadClass("com.example.MyUtil") → 类已加载,但 VERSION 还没被赋值(首次主动使用时才初始化)

什么时候必须用 Class.forName

需要类立即初始化的场景,典型如传统 JDBC 驱动注册(JDBC 4.0+ 已废弃该方式,但老项目仍大量存在)。

Java 6 之前,DriverManager 不自动扫描 META-INF/services/java.sql.Driver,必须靠 Class.forName("com.mysql.cj.jdbc.Driver") 触发驱动类的静态注册逻辑——它的 static 块里写了 DriverManager.registerDriver(new Driver())。

  • 显式依赖静态初始化副作用(如枚举单例、配置预加载、日志器绑定)
  • 反射调用前需确保类已「准备好」,比如某些框架校验 static final String MAGIC = "OK" 是否非空
  • 注意:Spring 的 ClassPathBeanDefinitionScanner 内部用的是 loadClass,避免过早初始化导致上下文启动失败

ClassLoader.loadClass 的实际用途和风险

它适合「仅检查类是否存在」或「延迟初始化」的场景,比如插件系统、热部署、或按需加载策略。但容易误以为「加载了就能用」,结果在首次访问字段/方法时抛 ExceptionInInitializerError。

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载

常见错误现象:NoClassDefFoundError 看似是类找不到,其实是初始化失败后 JVM 把类标记为「无效」,后续任何引用都报这个错(不是 ClassNotFoundException)。

  • 若你手动调用 loadClass 后立刻访问 clazz.getDeclaredFields(),没问题;但若调用 clazz.newInstance() 或读取 static 字段,可能当场崩溃
  • 不同 ClassLoader 实现行为一致,但自定义 ClassLoader 若重写了 loadClass 并偷偷调用了 resolveClass,就可能破环契约
  • Android 上 PathClassLoader 对 loadClass 有额外限制,部分系统类无法绕过初始化直接加载

如何安全地控制初始化时机

没有银弹,但可以组合使用并加防护。关键是别把「类加载」和「类可用」混为一谈。

如果需要加载但不确定是否初始化,建议显式补上初始化动作:Class.forName(name, false, cl)(不初始化)+ Class.forName(name, true, cl)(再初始化),或者更稳妥地捕获 ExceptionInInitializerError 并处理根本原因。

  • 优先用 Class.forName(name, false, cl) 替代裸 loadClass,语义更清晰
  • 对关键类做初始化探测:try { Class.forName(name); } catch (ExceptionInInitializerError e) { log.error("init failed", e); }
  • 避免在 static 块里写强依赖外部资源(DB、网络、文件)的逻辑——这会让 loadClass 和 forName 都变得脆弱

类初始化不是加载的附属动作,而是独立的、有明确触发条件的 JVM 规范行为。很多人调试时只盯着「类找没找到」,却忽略了「类是不是已经走完了初始化流程」——这才是最常被跳过的那一步。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11357

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8462

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7292

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1204

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

988

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1456

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2989

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20251

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1315

8

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习