虛擬機加載類的途徑 1、由 new 關鍵字建立一個類的實例 在由運行時刻用 new 方法載入 如:Dog dog = new Dog(); 2、調用 Class.forName() 方法 經過反射加載類型,並建立對象實例 如:Class clazz = Class.forName(「Dog」); Object dog =clazz.newInstance(); 3、調用某個 ClassLoader 實例的 loadClass() 方法 經過該 ClassLoader 實例的 loadClass() 方法載入。應用程序能夠經過繼承 ClassLoader 實現本身的類裝載器。 如:Class clazz = classLoader.loadClass(「Dog」); Object dog =clazz.newInstance(); 三者的區別: 1和2使用的類加載器是相同的,都是當前類加載器。(即:this.getClass.getClassLoader)。3由用戶指定類加載器。若是須要在當前類路徑之外尋找類,則只能採用第3種方式。第3種方式加載的類與當前類分屬不一樣的命名空間。另外,1是靜態加載,2、3是動態加載 兩個異常(exception) 靜態加載的時候若是在運行環境中找不到要初始化的類,拋出的是NoClassDefFoundError,它在JAVA的異常體系中是一個Error 動態態加載的時候若是在運行環境中找不到要初始化的類,拋出的是ClassNotFoundException,它在JAVA的異常體系中是一個checked異常 Class.forName與ClassLoader.loadClass區別 Class的裝載包括3個步驟:加載(loading),鏈接(link),初始化(initialize). Class.forName(className)其實是調用Class.forName(className, true, this.getClass().getClassLoader())。第二個參數,是指Class被loading後是否是必須被初始化。 ClassLoader.loadClass(className)實際上調用的是ClassLoader.loadClass(name, false),第二個參數指Class是否被link。 Class.forName(className)裝載的class已經被初始化,而ClassLoader.loadClass(className)裝載的class尚未被link。通常狀況下,這兩個方法效果同樣,都能裝載Class。但若是程序依賴於Class是否被初始化,就必須用Class.forName(name)了。 例如,在JDBC編程中,常看到這樣的用法,Class.forName(「com.mysql.jdbc.Driver」). 若是換成了getClass().getClassLoader().loadClass(「com.mysql.jdbc.Driver」),就不行。 com.mysql.jdbc.Driver的源代碼以下: // Register ourselves with the DriverManager static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException(「Can’t register driver!」); } } 原來,Driver在static塊中會註冊本身到java.sql.DriverManager。而static塊就是在Class的初始化中被執行。 因此這個地方就只能用Class.forName(className)。