ava中的Class.forName()和ClassLoader 均可以對類進行加載,在學習mysql期間可能會常常用到Class.forName(),ClassLoader負責將Class的字節碼形式轉換成內存形式的 Class 對象。字節碼能夠來自於磁盤文件,也就是XXXX.class,也能夠來自jar包裏的XXXX.class,也能夠來自遠程服務器提供的字節流,字節碼的本質就是一個字節數組[]byte。java
實際上Class.forName()方法也是調用的 ClassLoader 來實現的。forName方法最後調用 forName0(本地方法),第二個參數被默認設置爲了 true,這個參數表明是否對加載的類進行初始化,設置爲 true 時會類進行初始化,表明會執行類中的靜態代碼塊,以及對靜態變量的賦值等操做。mysql
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
他還有個重載方法,能夠手動選擇在加載類時是否要對其類進行初始化。sql
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader){}
編寫一個類測試一下。數據庫
public class Test {
static {
System.out.println("靜態代碼快");
}
public static final String title=getTitle();
private static String getTitle(){
System.out.println("執行getTitle()");
return "TITLE";
}
}
測試方法:數組
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("com.hxl.Test");
}
}
運行結果:服務器
靜態代碼快
執行getTitle()
根據運行結果得出 Class.forName 加載類時將類進了初始化,再看Classloader。ide
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader.getSystemClassLoader().loadClass("com.hxl.Test");
}
}
而 ClassLoader 的 loadClass 並無對類進行初始化,只是把類加載到了虛擬機中。學習
最後在說說JDBC,咱們使用 JDBC 時一般是使用 Class.forName() 方法來加載數據庫鏈接驅動。這是由於在 JDBC 規範中明確要求 Driver(數據庫驅動)類必須向 DriverManager 註冊本身。測試
以 MySQL 的驅動爲例,咱們看到 Driver 註冊到 DriverManager 中的操做寫在了靜態代碼塊中,這就是爲何在寫 JDBC 時使用 Class.forName() 的緣由了。ui
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance() }}