class.forName()

使用jdbc方式鏈接數據庫時會經常看到這句代碼:Class.forName(String className)。本文將淺顯地解讀這句代碼的含義。看這篇文章之前應該對java的反射機制有所瞭解,至少是對Class類有一定的瞭解。

官方文檔

初始化參數指定的類,並且返回此類對應的Class 對象(不瞭解Class類的同志,應該首先查看下java反射相關知識)。例如,以下代碼片段返回 java.lang.Thread 類對應的Class對象。

Class t = Class.forName(“java.lang.Thread”)

調用 forName(“X”) 將導致名爲 X 的類被初始化。

類裝載

類裝載指通過解析類(或者接口)的字節碼文件來構建代表這個類(或是這個接口)的實例的過程。有些像根據藍圖製作一個產品一樣的概念。類裝載有如下的兩種方式:

   1.Class c1 = Class.forName (String className);

                            2.ClassLoader cl = new  ClassLoader();

                           Class c1 = cl.loadClass(String className, boolean resolve );

兩種裝載方法的區別:

不同的類裝載器

Class.forName(String className)使用裝載當前類的類裝載器來裝載指定類。因爲class.forName(String className)方法內部調用了Class.forName(className, true, this.getClass().getClassLoader())方法,如你所見,第三個參數就是指定類裝載器,顯而易見,它指定的是裝載當前類的類裝載器的實例,也就是this.getClass().getClassLoader();

classLoader.loadClass(String className , boolean resolve);需要手動指定類裝載器的實例。

所以這兩種類裝載方式的區別之一是一個默認使用裝載當前類實例的類裝載器來裝載指定類,而另一個則需要手動指定一個類裝載器的實例。

是否實例化類

Class的裝載過程(也就是從字節碼文件到生成類的實例這個過程)分爲三個階段,loading(裝載),linking(連接)和initializing(實例化)。

上文提到Class.forName(className)方法內部調用了Class.forName(className, true, this.getClass().getClassLoader())方法。注意第二個參數,它指定Class被loading後是否要進行initializing操作。

ClassLoader.loadClass(className)方法內部調用ClassLoader.loadClass(name, false)方法,第二個參數指出Class在load之後,是否進行link操作。

區別就出來了。Class.forName(className)裝載的class已經被實例化,而ClassLoader.loadClass(className)裝載的class還沒有被link,所以就更談不上實例化了。

一般情況下,這兩個方法效果一樣,都能裝載Class。但如果程序需要Class被實例化,就必須用Class.forName(name)了。

在JDBC鏈接數據庫中的應用

在JDBC中加載驅動類時(關於加載jdbc驅動請參看另外一篇文章,<jdbc註冊驅動的三種方式>http://blog.csdn.net/yanwushu/article/details/7574708),Class.forName(“com.mysql.jdbc.Driver”),如果換成getClass().getClassLoader().loadClass(“com.mysql.jdbc.Driver”),就不行,因爲它只是向jvm裝載了Driver的類信息,但是並沒有實例化,也就不能執行相應的操作,因爲Driver是需要被初始化才能使用的。

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