爲什麼要寫Class.forName(String name)?

前言:

Class.forName(String name)
在用JDBC連接數據庫的時候,這句話經常是要寫的,老師常常告訴我們這個是加載數據庫驅動,書上也是這麼寫的,於是我們照葫蘆畫瓢,就這麼一直寫下來,但是作爲一個貪心的程序員,怎麼能止步於此呢?
看一下大佬是怎麼解釋的:

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();
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包。

轉載鏈接:https://blog.csdn.net/weixin_34406086/article/details/85760580?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章