源码:
(1)Class.forName(String name)生成指定类名或接口名的类对象(Class)。与方法等价:Class.forName(className, true, currentLoader),
currentLoader即定义当前类的类加载器。
(2)Class.forName:在方法区生成java.lang.Class对象。即类加载过程:通过全限定名获取类的二进制字节流,将二进制字节流转化为方法区的运行时数据结构。
(3)生成Class对象后,即可执行不依赖对象的静态块代码,如MySQL驱动的加载。
调用时不依赖实例化的对象。
变量或方法使用static关键字,调用时,无需new对象,使用类名即可。
类加载时,根据生成的Class对象完成调用。
package com.monkey.java_study.common.entity;
public class UserEntity {
private String uid;
private String nickname;
private String sex = "haha";
public UserEntity() {
}
static {
System.out.println(">>>>>>>>static function");
}
// 省略setter/getter/toString()
}
3.2 Class.forName()生成Class对象
使用Class.forName(String name)生成Class时,类加载过程中会直接调用静态代码块。
package com.monkey.java_study.database;
import com.monkey.java_study.common.entity.UserEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class DriverLoaderTest {
private static final Logger logger = LogManager.getLogger(DriverLoaderTest.class);
public static void main(String[] args) throws Exception {
Class userClass = Class.forName("com.monkey.java_study.common.entity.UserEntity");
}
}
执行结果:
MySQL注册驱动时,通过Class.forName(“com.mysql.cj.jdbc.Driver”)即完成了驱动注册。
代码如下:
package com.monkey.java_study.database;
import com.monkey.java_study.common.entity.UserEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import static com.monkey.java_study.common.constant.DatabaseConstant.*;
import static com.monkey.java_study.common.constant.DatabaseConstant.DB_MYSQL_PASSWORD;
public class DriverLoaderTest {
private static final Logger logger = LogManager.getLogger(DriverLoaderTest.class);
public static Connection databaseConnection() throws Exception {
// 注册MySQL驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 数据库连接地址
String DB_MYSQL_URL = "jdbc:mysql://localhost:3306/db_monkey_run?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
// 数据库用户名
String DB_MYSQL_USER_NAME = "root";
//数据库密码
String DB_MYSQL_PASSWORD = "123456";
return DriverManager.getConnection(DB_MYSQL_URL, DB_MYSQL_USER_NAME, DB_MYSQL_PASSWORD);
}
public static void main(String[] args) throws Exception {
Class userClass = Class.forName("com.monkey.java_study.common.entity.UserEntity");
Connection connection = databaseConnection();
}
}
这是为什么?
因为Driver驱动类中有一段静态代码块。静态代码块中通过DriverManager完成驱动注册,即:java.sql.DriverManager.registerDriver(new Driver());
源码如下:
package com.mysql.cj.jdbc;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
4 小结
- 方法区:静态区。装载class文件,存储类信息、常量和静态变量;静态代码块同样存储与方法区,不依赖于实例化的对象;
- Class.forName即在方法区加载指定的类,生成Class对象,同时直接加载类的静态代码块。
【参考文献】
[1]https://blog.csdn.net/qq_22059611/article/details/84347957
[2]https://www.cnblogs.com/dolphin0520/p/3799052.html



