2015-12-08 131 views
10

我一直與UrlClassLoader委託層次結構和繼承層次結構混淆。 我創建的類擴展URLClassLoader的和執行:childOfUrlClassLoader.getParent().getClass().getName() 這給了我: sun.misc.Launcher$AppClassLoader。 在此之後我拜訪上面的類(source)所提到UrlClassLoader委託和繼承層次結構

249 static class AppClassLoader extends URLClassLoader { 
     //... 
308  protected synchronized Class<?> loadClass(String name, boolean resolve) 
309   throws ClassNotFoundException 
310  { 
311   // First, check if the class has already been loaded 
312   Class c = findLoadedClass(name); 
313   if (c == null) { 
314    try { 
315     if (parent != null) { 
316      c = parent.loadClass(name, false); 
317  
      // ... 
329   return c; 
330  } 

然後我查誰是AppClassLoader的父。預計我得到sun.misc.Launcher$ExtClassLoader和ExtClassLoader的父母是null


我有幾個問題:

1)誰給我班自AppClassLoader.loadClass代碼有行

294 return (super.loadClass(name, resolve)); 

它看起來像循環,不是嗎?

2)爲什麼不具備的ExtClassLoader作爲BootstrapClassLoader父母,但null

3)爲什麼AppClassLoader類擴展UrlClassLoader?

回答

7

代表,第一種模式

構建的Java類加載器遵循一個代表第一個模型。這意味着一個ClassLoader將允許它的父代在它自己加載它之前加載一個類。加載程序的層次結構在頂部具有引導加載程序,其後是擴展類加載程序,即應用程序類加載程序。在應用程序類加載器下可以找到URLClassLoaders和由應用程序創建的任何其他加載器。

自舉類加載器可以從包含最重要的Java類,包括那些在java.lang,java.io,java.util中和java.net包rt.jar中加載文件。擴展類加載器從Java安裝中的其他jar文件加載類。它是應用程序類加載器,用於加載在類路徑中找到的類,並在應用程序啓動時加載當前的類加載器。

加載在行動

那麼,當一個應用程序需要加載一個HashMap發生什麼呢?當前的類加載器被要求加載HashMap類。在嘗試任何事情之前,它會要求其父母,擴展類加載器加載該類。反過來,擴展類加載器指派給引導類加載器,它在rt.jar中找到類並加載它。

如果要加載的類在classpath中,要求上升到引導類加載器之前檢查rt.jar中。引導程序加載程序無法找到該類,因此該任務將返回到擴展類加載程序,該程序會在java安裝中搜索該類。當此失敗時,任務將恢復到應用程序類加載器,該類將掃描類的類路徑。

類加載器的緩存

實際上,每個類加載器具有這樣的類已經加載存儲在緩存和緩存代表團到父面前搜查,但是這並沒有改變最初委託的原則。

這是高速緩存檢查

Class c = findLoadedClass(name); 

URLClassLoaders

由應用程序創建將具有應用類加載器作爲父甲的URLClassLoader。如果它遵循委託優先模型,則可以在提供的URL之前的類路徑中找到類。

誰給我的課的問題

1)

我看到略有不同的代碼在你的鏈接

309   // First, check if the class has already been loaded 
310   Class c = findLoadedClass(name); 
311   if (c == null) { 
312    try { 
313     if (parent != null) { 
314      c = parent.loadClass(name, false); 
315     } else { 
316      c = findBootstrapClass0(name); 
317     } 
318    } catch (ClassNotFoundException e) { 
319     // If still not found, then invoke findClass in order 
320     // to find the class. 
321     c = findClass(name); 
322    } 
323   } 

如果一個類中不屬於母公司加載,它拋出一個被捕獲的ClassNotFoundException並允許當前ClassLoader找到類

321     c = findClass(name); 

2)爲什麼ExtClassLoader不具有BootstrapClassLoader作爲父項,但具有null?

這由getClassLoader API

[getClassLoader()]返回類加載器類回答。某些實現可能使用null來表示引導類加載器。

3)爲什麼AppClassLoader類擴展了UrlClassLoader?

請注意,應用程序類加載器並不特別,它加載的是用戶提供的類,而不是系統類。類路徑實際上是一個URI列表,所以URLClassLoader是一個合適的超類。

參考

上有許多類加載的文章,包括