Java類加載器(ClassLoader)
雙親委派模式要求除了頂層的啟動類加載器外,其余的類加載器都應當有自己的父類加載器,請注意雙親委派模式中的父子關系并非通常所說的類繼承關系,而是采用組合關系來復用父類加載器的相關代碼,類加載器間的關系如下:
TIM截圖20190116163949.png
雙親委派模式是在Java 1.2后引入的,其工作原理的是,如果一個類加載器收到了類加載請求,它并不會自己先去加載,而是把這個請求委托給父類的加載器去執行,如果父類加載器還存在其父類加載器,則進一步向上委托,依次遞歸,請求最終將到達頂層的啟動類加載器,如果父類加載器可以完成類加載任務,就成功返回,倘若父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式
3 雙親委派模式優勢
- 采用雙親委派模式的是好處是Java類隨著它的類加載器一起具備了一種帶有優先級的層次關系,通過這種層級關可以避免類的重復加載,當父親已經加載了該類時,就沒有必要子ClassLoader再加載一次。
- 其次是考慮到安全因素,java核心api中定義類型不會被隨意替換,假設通過網絡傳遞一個名為java.lang.Integer的類,通過雙親委托模式傳遞到啟動類加載器,而啟動類加載器在核心Java API發現這個名字的類,發現該類已被加載,并不會重新加載網絡傳遞的過來的java.lang.Integer,而直接返回已加載過的Integer.class,這樣便可以防止核心API庫被隨意篡改。
- 可能你會想,如果我們在classpath路徑下自定義一個名為java.lang.SingleInterge類(該類是胡編的)呢?該類并不存在java.lang中,經過雙親委托模式,傳遞到啟動類加載器中,由于父類加載器路徑下并沒有該類,所以不會加載,將反向委托給子類加載器加載,最終會通過系統類加載器加載該類。但是這樣做是不允許,因為java.lang是核心API包,需要訪問權限,強制加載將會報出如下異常
java.lang.SecurityException: Prohibited package name: java.lang