class.forname用于触发驱动类静态块执行以注册jdbc驱动;因jdbc 4.0起spi自动加载,现无需显式调用,仅历史兼容或特殊场景使用。

在 Java 中,Class.forName 曾是 JDBC 传统加载数据库驱动的方式,主要用于触发驱动类的静态初始化块(如 DriverManager.registerDriver),从而将驱动注册到 JDBC 管理器中。不过从 JDBC 4.0(Java 6 起)开始,**已不再需要显式调用 Class.forName** —— 只要驱动 JAR 在类路径中,JDBC 会自动通过 SPI(Service Provider Interface)机制发现并注册驱动。
为什么以前要用 Class.forName?
早期 JDBC(如 MySQL Connector/J 5.x 及更早版本)的驱动类(如 com.mysql.jdbc.Driver)在静态代码块中主动向 DriverManager 注册自己:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException e) {
throw new RuntimeException("Can't register driver!");
}
}
}
调用 Class.forName("com.mysql.jdbc.Driver") 就是为了强制执行该静态块,完成注册。
常见驱动类名(仅作历史参考)
不同数据库旧版驱动对应的类名如下(新版驱动已弃用这些方式):
- MySQL 5.x:
com.mysql.jdbc.Driver - MySQL 8.x(兼容模式):
com.mysql.cj.jdbc.Driver(仍可工作,但非必需) - PostgreSQL:
org.postgresql.Driver - Oracle(ojdbc8):
oracle.jdbc.driver.OracleDriver(已过时,推荐使用oracle.jdbc.OracleDriver或直接依赖自动加载) - HSQLDB:
org.hsqldb.jdbc.JDBCDriver
现在该怎么写?(推荐做法)
✅ 完全省略 Class.forName,直接获取连接:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC"; Connection conn = DriverManager.getConnection(url, "user", "pass");
前提是:
- JDBC 驱动 JAR(如
mysql-connector-java-8.0.33.jar)在 classpath 中 - 驱动 JAR 的
META-INF/services/java.sql.Driver文件存在且内容正确(现代驱动都自带)
⚠️ 若仍手动调用 Class.forName,不会报错,但属于冗余操作;某些新版驱动(如较新 HikariCP + MySQL 8)甚至会在日志中提示 “driver registered via SPI, Class.forName is unnecessary”。
什么情况下可能还需用到它?
极少数特殊场景,例如:
- 动态加载某个不在启动 classpath 中的驱动(需配合
URLClassLoader) - 旧项目维护,尚未升级 JDBC 驱动或 JDK 版本(如仍在用 JDK 5 或 MySQL 3.x)
- 教学演示“类加载与静态初始化”的原理
示例(不推荐生产使用):
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException("MySQL driver not found", e);
}
Connection conn = DriverManager.getConnection(url, user, pass);
现代 Java 应用应依赖 JDBC SPI 自动发现机制,专注连接参数、连接池配置和异常处理,不必再为驱动加载操心。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










