Class.forName 和 ClassLoader 的區別?面試常見題

Class.forName 和 ClassLoader 的區別?面試常見題

其實人生一瞬間,有機會就要拼,成功失敗與否,要的是結果而享受的是過程。沒有坎坷崎嶇不叫命運,沒有大風大浪不叫人生 。

前言

在 java中Class。forName()和ClassLoader都可以對類進行載入。ClassLoader就是遵循雙親委派模型最終呼叫啟動類載入器的類載入器,實現的功能是“透過一個類的全限定名來獲取描述此類的二進位制位元組流”,獲取到二進位制流後放到 JVM 中。Class。forName() 方法實際上也是呼叫的 CLassLoader 來實現的。

Class.forName 和 ClassLoader 的區別?面試常見題

Class。forName(String className)

這個方法的原始碼是:

Class.forName 和 ClassLoader 的區別?面試常見題

最後呼叫的方法是 forName0 這個方法,在這個 forName0 方法中的第二個引數被預設設定為了 true,這個引數代表是否對載入的類進行初始化,設定為 true 時會類進行初始化,代表會執行類中的靜態程式碼塊,以及對靜態變數的賦值等操作。

也可以呼叫 Class。forName(String name, boolean initialize,ClassLoader loader) 方法來手動選擇在載入類的時候是否要對類進行初始化。Class。forName(String name, boolean initialize,ClassLoader loader) 的原始碼如下:

Class.forName 和 ClassLoader 的區別?面試常見題

原始碼中的註釋只摘取了一部分,其中對引數 initialize 的描述是:if {@code true} the class will be initialized。 意思就是說:如果引數為 true,則載入的類將會被初始化。

舉例:

下面還是舉例來說明結果吧:一個含有靜態程式碼塊、靜態變數、賦值給靜態變數的靜態方法的類。

Class.forName 和 ClassLoader 的區別?面試常見題

測試方法:

Class.forName 和 ClassLoader 的區別?面試常見題

執行結果:

Class.forName 和 ClassLoader 的區別?面試常見題

根據執行結果得出 Class。forName 載入類是將類進了初始化,而 ClassLoader 的 loadClass 並沒有對類進行初始化,只是把類載入到了虛擬機器中。

應用場景

在我們熟悉的 Spring 框架中的 IOC 的實現就是使用的 ClassLoader。

而在我們使用 JDBC 時通常是使用 Class。forName() 方法來載入資料庫連線驅動。這是因為在 JDBC 規範中明確要求 Driver(資料庫驅動)類必須向 DriverManager 註冊自己。

以 MySQL 的驅動為例解釋:

Class.forName 和 ClassLoader 的區別?面試常見題

我們看到 Driver 註冊到 DriverManager 中的操作寫在了靜態程式碼塊中,這就是為什麼在寫 JDBC 時使用 Class。forName() 的原因了。