龙空技术网

面试题:Class.forName加载驱动的目的,不用这种方式可以吗?

老嗨 1181

前言:

现在同学们对“java加载驱动程序失败”都比较重视,姐妹们都想要知道一些“java加载驱动程序失败”的相关资讯。那么小编同时在网络上网罗了一些对于“java加载驱动程序失败””的相关资讯,希望你们能喜欢,同学们一起来了解一下吧!

本篇主要是分析创建数据库连接时的Class.forName的作用以及其替代方法。

下面是获取数据库连接的通用写法:

Class.forName(driver);Connection conn = DriverManager.getConnection(url, username, password);

不过在解释具体原因之前先简单了解Class.forName的作用。

现在假设一个类还没有被装进内存,Class.forName(String className)这个方法会做以下几件事情:

1、装载。将字节码读入内存,并产生一个与之对应的java.lang.Class类对象2、连接。这一步会验证字节码,为static变量分配内存,并赋默认值(0或null)(注意:实例变量这里不会分配内存)。比如:public static int a = 1;这一步过后a的值为0而不是1.3、初始化。执行类变量的赋值动作和静态代码块。即为类的static变量赋初始值,那么上面这个将a赋值为1的操作就是这个时候做的。除此之外,还要调用类的static块(这一步是关键)。这里只是简单描述一下过程,其实jvm做的事远比这些复杂得多。

根据上面的分析,猜测driver类中应该有静态代码块执行某些操作,让我们进入到driver类看下里面有没有static块,这里以com.mysql.jdbc.Driver为例:

从上面的代码可以看到这一句: java.sql.DriverManager.registerDriver(new Driver());

DriverManager类是用来管理数据库中的所有驱动程序的,是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接。此外,DriverManager类中的方法都是静态方法,所以在程序中无须对它进行实例化,直接通过类名就可以调用

那我们是不是可以用DriverManager.registerDriver来替代Class.forName,测试一下发现能获取到连接:

即然如此按照上面的分析我们也可以直接new Driver();如下也是可以获取到连接的

不过我们还是推荐使用Class.forName,因为DriverManager.registerDriver和new Driver都会多创建了一个driver实例。

另:从jdk1.6开始提供spi机制,对于驱动包下含有/META-INF/services/java.sql.Driver文件的包,可以不用显式的调用Class.forName加载驱动了,调用DriverManager.getConnection时会通过spi机制加载合适的驱动。

这个读者朋友们可以自己尝试下。

标签: #java加载驱动程序失败