Java基礎:JDBC學習2之為什麼要寫Class.forName("XXX")?

Class.forName(String name)

接上一篇JDBC。本來這個內容是放在前面的一篇裡面的一起的,後來發現越寫越多,想想看就算了,還是單獨開一篇文章好了,這樣也能寫得更加詳細點。

上一篇文章的第4點,getConnection()方法裡面,我把從.properties裡面獲取mysqlpackage的地方替換成實際的value值,那麼替換後的應該是Class.forName("com.mysql.jdbc.Driver"),實際上所有的JDBC連接先寫的基本上也都是這一句。另外,哪怕刪除這一句,也是可以運行成功的。那為什麼還要Class.forName("com.mysql.jdbc.Driver")呢?OK,分點講解。

1、為什麼要Class.forName("com.mysql.jdbc.Driver")?

JDBC是23種模式中的橋接模式的典型應用,熟悉橋接模式的基本上稍微看一下源代碼就知道為什麼了,那橋接模式這裡不講,只講為什麼要這麼做。Class.forName(String className)的作用有兩個,第一是CLASSPATH下指定名字的.class文件加載到Java虛擬機內存中, 第二是初始化這個類。看到這句話,返回值都沒有,那寫在這裡的作用很明顯了,就是初始化"com.mysql.jdbc.Drvier"。初始化做了什麼?給靜態資源賦值以及執行靜態代碼塊,所以,反編譯一下"mysql-connector-java-5.1.20-bin.jar"這個jar包,查看一下Driver類:

public class Driver extends NonRegisteringDriver
implements java.sql.Driver
{
public Driver()
throws SQLException
{

}
static
{
try
{
DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}

看到Class.forName("com.mysql.jdbc.Driver")的作用實際上就是調用DriverManager的registerDriver方法註冊一個mysql的JDBC驅動(Driver)而已,Driver繼承NonRegisteringDriver.java,NonRegisteringDriver.java實現了JDK提供的Driver接口,這個Driver提供了若干數據庫連接的方法,每個不同的數據庫連接類都必須實現它,並重寫和具體的數據庫連接的算法。DriverManager也是JDK中的類,截一些關鍵代碼:

private static final CopyOnWriteArrayList<driverinfo> registeredDrivers = new CopyOnWriteArrayList();
/<driverinfo>
Public static synchronized void registerDriver(Driver paramDriver)
throws SQLException
{
if (paramDriver != null)
registeredDrivers.addIfAbsent(new DriverInfo(paramDriver));
else
throw new NullPointerException();
println("registerDriver: " + paramDriver);
}

底層利用了一個CopyOnWriteArrayList作為容器(這是一個線程安全的容器,不過每次add的時候都會對底層數組進行一次新的複製,所以在讀遠多於寫的時候建議可以使用這個),放那些註冊進去的DriverInfo。最終getConnection(...)的時候就拿registerDrivers裡面註冊進去的具體的某個數據庫的DriverInfo(像MySql的Driver就在DriverInfo裡面)去連接具體的數據庫。OK,所以總結一下整個流程:

JDK不負責和數據庫連接打交道,也沒必要,只提供一個具體的接口Driver,告訴所有第三方,要連接數據庫,就去實現這個接口,然後通過DriverManager註冊一下,到時候連接某個數據庫的時候,你已經在我這裡註冊了,我會調用你註冊進來的Driver裡面的方法去對指定數據庫進行連接的。然後Mysql就實現自己的Driver,Oracle就實現自己的Driver,通過static塊註冊一下,再然後,就沒有然後了。

2、為什麼不直接new?

意思是這麼寫"com.mysql.jdbc.Driver d = new com.mysql.jdbc.Driver();",可以啊,因為在new的時候會自動觸發對一個類的初始化。問題是new出來幹嘛?com.mysql.jdbc.Driver裡面的方法我們會用到嗎,並且我們知道怎麼用嗎?僅僅為了初始化一個類而new一個類實例出來還不如不去new,直接使用Class.forName(String name)初始化就可以了。DriverManager類的getConnection(...)方法的存在本身就是幫助用戶調用Driver裡面的各種方法連接數據庫,JDK都做好了,開發者就沒必要自己寫了。

3、為什麼刪除Class.forName("com.mysql.jdbc.Driver")還是可以運行?

1996年1月23日JDK1.0發佈,Java語言有了第一個正式版本的運行環境。JDBC是1997年2月19日,在JDK1.1的版本中發佈的,從版本就看得出,JDBC屬於Java技術的一些最基礎的功能點。那在JDK1.5之後,其實已經不需要去顯式調用Class.forName("com.mysql.jdbc.Driver")了,DriverManager會自動去加載合適的驅動,但是前提是

CLASSPATH下必須有驅動jar包

Java基礎:JDBC學習2之為什麼要寫Class.forName(


分享到:


相關文章: