Class.forName() 是如何工作的?

新手上路,请多包涵

我刚刚了解到 java.sql package 。它使用 Class.forName() 动态加载扩展 DriverManager 的驱动程序。然后我们使用 DriverManager.getConnection() 方法获得连接。

那么整个事情是如何运作的呢?

DriverManager 类如何知道如何在不使用实际驱动程序的类名的情况下获取连接。

我们也可以将 Class.forName() 用于自定义应用程序……如果用示例对此进行解释,我将非常高兴。

原文由 SonOfTheEARTh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 614
2 个回答

Class.forName 简单地加载一个类,包括运行它的静态初始化程序,如下所示:

 class Foo {
    static {
        System.out.println("Foo initializing");
    }
}

public class Test {
    public static void main(String [] args) throws Exception {
        Class.forName("Foo");
    }
}

您正在谈论的所有其余过程都是特定于 JDBC 的。驱动程序 - 实现 Driver ,它不扩展 DriverManager 只是使用 DriverManager.registerDriver 注册一个适当的实例。然后当 DriverManager 需要为特定连接字符串查找驱动程序时,它依次调用 connect 对每个已注册的驱动程序,直到一个成功并返回一个非空连接。

请注意,这种注册驱动程序的方式相当过时 - 查看文档 DriverManager 了解获取数据源的更现代方式。

原文由 Jon Skeet 发布,翻译遵循 CC BY-SA 4.0 许可协议

当我们使用 new 运算符创建一个类的实例时,它做了两件事

  1. 将类加载到内存中(如果未加载)——这意味着从 .class 文件创建类的内存表示,以便可以从中创建实例。这包括初始化静态变量(解析该类)
  2. 创建该类的实例并存储对变量的引用。

Class.forName 只做第一件事。它将类加载到内存中并将该引用作为类的实例返回。如果我们想创建一个实例,我们可以调用该类的 newInstance 方法。这将调用默认构造函数(无参数构造函数)。请注意,如果默认构造函数不可访问,则 newInstance 方法将抛出 IllegalAccessException 。如果该类是抽象类或接口,或者它没有默认构造函数,那么它将抛出 InstantiationException 。如果在解析该类期间出现任何异常,它将抛出 ExceptionInInitializerError

如果未定义默认构造函数,则我们必须使用反射 API 调用 defiend 构造函数。

但是 Class.forName 的主要优点是,它可以接受类名作为 String 参数。所以我们可以动态传递类名。但是如果我们使用 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 注册

因此,如果您使用新的 Operator,则必须执行以下操作。

代码:

 Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);

原文由 Shubham Verma 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题