Java連接模型允許用戶自行定義類裝載器,這樣一來就可以在運行時定製地擴展用戶的程序。通過用戶自定義的類裝載器,你的程序可以裝載在編譯時並不知道或許尚未存在的類或者接口,並動態連接他們。
1.動態連接和解析
當編譯Java程序的時候,會得到程序中每一個類或者接口的獨立的class文件。雖然獨立看上去毫無關聯,但是他們之間通過接口符號互相聯繫,或者與Java API的class文件相聯繫。
class把他們所有的引用符號放在一個地方——常量池。每一個class文件有一個常量池,每一個被Java虛擬機裝載的類或者接口都有一份內部版本常量池,被稱作運行時常量池。運行時常量池是特定與實現的數據結構,數據結構映射到class文件中的常量池。因此,當一個類型被首次裝載的時候,所有來自於類型的符號引用都裝載到了類型的運行時常量池。
在程序運行的過程中,如果某個特定的符號引用將要被使用,它首先要被解析。解析過程就是首先根據符號引用查找到實體,再把符號引用替換成直接引用的過程。因爲所有的符號引用都是保存在常量池中,所以這種解析叫做常量池解析。
連接不僅僅包括把符號引用替換成直接引用,還包括檢查正確性和權限。
1.1解析和動態擴展
Java體系允許程序動態的擴展Java程序,這個過程包括運行時決定所使用的類型,裝載它們,使用它們。通過傳遞類型的名字到java.lang.Class的forName()方法,或者用戶自定義的類裝載器的loadClass()方法,可以動態擴展Java程序。
public static Class forName(String className,boolean initialize,ClassLoader loader) throws ClassNotFoundException;
如果initialize爲true,則在forName方法返回前會對類型進行裝載,連接,初始化,如果爲false,類型會被裝載,可能會被連接,但不會被初始化。loader傳遞一個用戶定製的類裝載器的引用給forName(),讓其使用這個類裝載器來請求類型。
動態擴展java程序的另外一種方式就是使用用戶自定義類裝載器的loadClass()方法,如果需要用自定義的類裝載器請求類型,只需要調用那個類裝載器的loadClass()方法。
如果要求裝載完成就初始化的話用forName()方法。如果安全要求的話用loadClass(),因爲它們有不同的命名空間。
1.2類裝載器和雙親委派模型
1.3常量池解析
1.4