使用JDBC時Class.Forname()的作用

使用JDBC時,我們都會很自然得使用下列語句:

java 代碼
  1. Class.forName( "com.mysql.jdbc.Driver" );   
  2. String url =  "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8" ;   
  3. String user =  "" ;   
  4. String psw =  "" ;   
  5. Connection con = DriverManager.getConnection(url,user,psw);  


    爲什麼說很自然呢,因爲無論是網上還是書本教程上得例子都是這樣的,而且程序也確實正常運行了,於是大家也就心安理得的找葫蘆畫瓢下去了。
    一定要有這一句嗎?不是的,我們完全可以用這樣一句代替它:

java 代碼
  1. com.mysql.jdbc.Driver driver =  new  com.mysql.jdbc.Driver();   
  2. //or:   
  3. //new com.mysql.jdbc.Driver();   
  4. String url =  "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8" ;   
  5. String user =  "" ;   
  6. String psw =  "" ;   
  7. Connection con = DriverManager.getConnection(url,user,psw);   
  8.   

 

    大家可能都看出個大概來了,我們只需要在調用DriverManager的getConnection方法之前,保證相應的Driver類已經被加載到 jvm中,並且完成了類的初始化工作就行了,而具體是怎樣實現這個功能卻是沒有講究的。上面兩種方法都可以實現這個功能,因此程序可以正常運行。注意了, 如果我們進行如下操作,程序是不能正常運行的,因爲這樣僅僅使Driver類被裝載到jvm中,卻沒有進行相應的初始化工作。

java 代碼
  1. com.mysql.jdbc.Driver driver =  null ;   
  2. //or:   
  3. ClassLoader cl =  new  ClassLoader();   
  4. cl.loadClass( "com.mysql.jdbc.Driver" );  


     我們都知道JDBC是使用Bridge模式進行設計的,DriverManager就是其中的Abstraction,java.sql.Driver是 Implementor,com.mysql.jdbc.Driver是Implementor的一個具體實現(請參考GOF的Bridge模式的描 述)。大家注意了,前一個Driver是一個接口,後者卻是一個類,它實現了前面的Driver接口。
     Bridge模式中,Abstraction(DriverManager)是要擁有一個Implementor(Driver)的引用的,但是我們在使 用過程中,並沒有將Driver對象註冊到DriverManager中去啊,這是怎麼回事呢?jdk文檔對Driver的描述中有這麼一句:
     When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager
哦,原來是com.mysql.jdbc.Driver在裝載完後自動幫我們完成了這一步驟。源代碼是這樣的:

java 代碼
  1. package  com.mysql.jdbc   
  2.   
  3. public   class  Driver  extends  NonRegisteringDriver  implements  java.sql.Driver {   
  4.   // ~ Static fields/initializers   
  5.   // --------------------------------------------- //   
  6.   // Register ourselves with the DriverManager   
  7.   //   
  8.   static  {   
  9.     t ry {   
  10.               java.sql.DriverManager.registerDriver( new  Driver());   
  11.           }  catch  (SQLException E) {   
  12.                throw   new  RuntimeException( "Can't register driver!" );   
  13.           }   
  14.   }   
  15. // ~ Constructors   
  16.   // -----------------------------------------------------------   
  17. /**  
  18.   * Construct a new driver and register it with DriverManager  
  19.   *   
  20.   * @throws SQLException  
  21.   *             if a database error occurs.  
  22.   */   
  23.   public  Driver()  throws  SQLException {   
  24.       // Required for Class.forName().newInstance()   
  25.  }   
  26. }
  27. 這裏ClassLoader爲什麼不行,是類加載器的機制決定的 www.javaeye.com/topic/25053

    static塊在什麼時候執行?
    1)當調用forName(String)載入class時執行,如果調用ClassLoader.loadClass並不會執行.forName(String,false,ClassLoader)時也不會執行.
    2)如果載入Class時沒有執行static塊則在第一次實例化時執行.比如new ,Class.newInstance()操作
    3)static塊僅執行一次

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