当我们使用 new 操作符创建一个类的实例时,它会做两件事
- 将类加载到内存中,如果没有加载 -
这意味着从 .class 文件创建类的内存表示,以便可以从中创建实例。这包括初始化静态变量(解析该类)
- 创建该类的实例并存储对变量的引用。
Class.forName 只做第一件事。
它将类加载到内存中,并将该引用作为 Class 的实例返回。如果我们想创建一个实例,我们可以调用该类的 newInstance 方法。这将调用默认构造函数(无参数构造函数)。
请注意,如果默认构造函数不可访问,则 newInstance 方法将抛出 IllegalAccessException。如果该类是一个抽象类或接口,或者它没有默认构造函数,那么它将抛出一个InstantiationException。如果在解析该类期间出现任何异常,它将抛出 ExceptionInInitializerError。
如果没有定义默认构造函数,那么我们必须使用反射API调用defiend构造函数。
但是 Class.forName 的主要优点是,它可以接受类名作为字符串参数。所以我们可以动态传递类名。但是如果我们使用new操作符创建一个类的实例,类名就不能动态改变了。
Class.forName() 反过来会调用调用者 ClassLoader 的 loadClass 方法(调用 Class.forName 的类的 ClassLoder)。
默认情况下,Class.forName() 解析该类。这意味着,初始化该类中的所有静态变量。
同样可以使用Class.forName(String name,boolean initialize,ClassLoader loader)的重载方法来改变
使用Class.forName()加载jdbc驱动的主要原因是驱动可以动态变化。
在静态块中,所有驱动程序将创建自己的一个实例,并使用 DriverManager.registerDriver() 方法向 DriverManager 注册该类。由于Class.forName(String className) 默认解析类,它将初始化静态初始化程序。
所以当我们打电话给Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver")时,
Driver 类将被加载、实例化并注册到 DriverManager
因此,如果您使用 new Operator,则必须执行以下操作。
代码:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);