天天看点

关于Class.forName

前言

相信大家在使用反射操作时多多少少能用到这个方法。如果你使用了mysql数据库并且使用了原生的数据库操作,你肯定有一段这样的代码​

​Class.forName("com.mysql.jdbc.Driver");​

​​ 这段代码的意义就是生成一个代表com.mysql.jdbc.Driver类的java.lang.Class对象到内存中,作为方法区这个类的各种数据的入口,在执行初始化操作时调用该类静态代码块。

查看​​

​com.mysql.jdbc.Driver​

​ 类

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!");
        }
    }

    /**
     * Construct a new driver and register it with DriverManager
     * 
     * @throws SQLException
     *             if a database error occurs.
     */
    public Driver() throws SQLException {
        // Required for Class.forName().newInstance()
    }
}      

在Driver类中有一个静态代码块,在执行​

​Class.forName("com.mysql.jdbc.Driver");​

​​会执行该代码块,做的就是注册驱动,这样在后续的​

​DriverManager.getConnection​

​操作才能使用我们的驱动来获取数据库连接。

使用class.forName

使用​

​class.forName​

​​方法本质上做的就是类的加载。

类的加载分为:

加载、验证、准备、解析、初始化、使用、卸载。

class.forName有两个重载方法

forName(String className)      
forName(String name, boolean initialize,ClassLoader loader)      
  • 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
  • 定义对象数组,不会触发该类的初始化。
  • 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
  • 通过类名获取Class对象,不会触发类的初始化。
  • 通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。
  • 通过ClassLoader默认的loadClass方法,也不会触发初始化动作。