我刚学会了java.sql package.它用于Class.forName()动态加载扩展的驱动程序DriverManager.然后我们使用DriverManager.getConnection()方法获得连接.
那么整个过程如何运作?
DriverManager类如何在不使用实际驱动程序的类名的情况下知道如何获取连接.
我们也可以将Class.forName()用于自定义应用程序......如果用一个例子来解释,我将非常高兴.
Jon*_*eet 66
Class.forName 只需加载一个类,包括运行其静态初始值设定项,如下所示:
class Foo {
static {
System.out.println("Foo initializing");
}
}
public class Test {
public static void main(String [] args) throws Exception {
Class.forName("Foo");
}
}
Run Code Online (Sandbox Code Playgroud)
您正在讨论的所有其余过程都是特定于JDBC的.驱动程序 - 它实现Driver,不扩展DriverManager- 只是使用注册一个适当的实例DriverManager.registerDriver.然后,当DriverManager需要为特定连接字符串找到驱动程序时,它connect依次调用每个已注册的驱动程序,直到有人说"是的,我可以成为该连接的驱动程序".
请注意,这种注册驱动程序的方式相当老套 - 查看文档以DriverManager获取更现代的数据源获取方式.
Shu*_*rma 20
当我们使用new运算符创建类的实例时,它会做两件事
Class.forName只做第一件事.它将类加载到内存中,并将该引用作为Class的实例返回.如果我们想创建一个实例,那么我们可以调用该类的newInstance方法.这将调用默认构造函数(无参数构造函数).请注意,如果无法访问默认构造函数,则newInstance方法将抛出一个IllegalAccessException.如果类是抽象类或接口,或者它没有默认构造函数,那么它将抛出一个InstantiationException.如果在解析该类时有任何异常,则会抛出一个异常ExceptionInInitializerError.
如果未定义默认构造函数,那么我们必须使用反射API调用defiend构造函数.
但Class.forName的主要优点是,它可以接受类名作为String参数.所以我们可以动态传递类名.但是如果我们使用new运算符创建类的实例,则无法动态更改类名.
Class.forName()inturn将调用调用者ClassLoader的loadClass方法(调用where的类的ClassLoder Class.forName).
默认情况下,Class.forName()解析该类.这意味着,初始化该类中的所有静态变量.同样可以使用重载方法更改Class.forName(String name,boolean initialize,ClassLoader loader)
使用jdbc驱动程序加载的主要原因Class.forName()是,驱动程序可以动态更改.在静态块中,所有驱动程序将创建自身的实例,并使用DriverManager.registerDriver()方法使用DriverManager注册该类.由于Class.forName(String className)默认情况下解析类,因此它将初始化静态初始化程序.因此,当我们调用时Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver"),Driver类将被加载,实例化并向DriverManager注册
因此,如果您使用的是新操作员,则必须执行以下操作.
码:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
Run Code Online (Sandbox Code Playgroud)
Boz*_*zho 16
Class.forName(..)加载并初始化目标类.这反过来意味着调用静态初始化程序块(代码定义为static { .. }.
例如,如果你看一下MySQL的驱动程序,那个驱动程序就会在那个静态块中注册自己: DriverManager.registerDriver(new Driver());
Class.forName(..)如果你能"负担"MySQL驱动程序的编译时依赖性,你可以省略并自己注册驱动程序.
也就是说,用于Class.forName(..)从应用程序初始化类很少是相关的,因为编译时依赖性不是问题.
另请注意,从版本4开始,JDBC Class.forName(..) 不再需要.通过使用服务提供程序机制,您可以指示驱动程序管理器由系统属性加载的内容.