2011-03-29 38 views
9

我已閱讀文檔,但我仍然不明白應該提供哪個類加載器作爲參數。我嘗試了幾個選項,但這似乎對編譯或代理的行爲沒有影響。我有點不安,我可以通過任何類加載器參數傳遞任何東西,包括null,並且代碼仍然正常工作。任何人都可以解釋這一點,並告訴我,如果我爲類加載器提供了一個錯誤的參數,會出現什麼樣的錯誤?我應該補充一點,就Java或一般來說,我並沒有對類加載器的強大直觀概念。我應該向Proxy.newProxyInstance(...)提供哪個ClassLoader?

回答

6

任何類都需要有一個類加載器,因此我們必須在這裏給出一個。

的重要組成部分,這是(在the documentation for getProxyClass()):

所有接口類型都必須通過指定的類加載器是按名稱可見。換句話說, 的類加載器CL和每一個接口I,下面的表達式必須爲真:

Class.forName(i.getName(), false, cl) == i 

所以,你可以使用任何類加載器,其中它的父類加載器的一個(或多個)定義的給定接口。

如果null適用於你的情況,我想你的接口也有null類加載器(引導加載程序) - 那麼你使用哪個類加載器應該沒有關係。如果你必須從你不知道的接口創建一個代理,只需要給出第一個接口的類加載器,並希望你的調用者不會做一些奇怪的事情。

爲什麼需要它?

你可以把它想象這樣的:

  • getProxyClass()方法創建(如果不存在的話)實現所有接口的所有方法的新類的一些字節碼(每個人只是轉發致電InvocationHandler)。
  • 然後它將這個字節碼傳遞給您指定的類加載器的defineClass方法。
  • 在此字節碼中,您的所有接口都按名稱引用,現在VM使用引用的forName調用來解析這些接口。

我們可以用純Java已經實現了這個getProxyClass這種方式沒有任何VM魔法,但我們需要創建一個新的類加載器(與指定一個作爲家長),因爲它不是能夠重新使用現有的一。

在現實中可能不存在此合成類實際字節碼,因爲虛擬機能夠在這裏使用其內部的魔法:-)

+0

謝謝,我仍然沒有什麼類加載器做的直覺。你能提一點關於這個嗎?我仍然很難理解爲什麼一個null類加載器可能會工作,如果類加載器負責做任何實質性的事情。也許一個玩具的例子給出了錯誤的類加載器? – jonderry 2011-03-30 01:24:34

+0

'null'類加載器是「引導類加載器」,加載核心類的類加載器(比如'Class','Object','ClassLoader')。它由VM本地實現,並沒有ClassLoader對象。 (它被Class使用。例如,如果你給'null'作爲'ClassLoader'參數)。 (例子會晚點來。) – 2011-03-30 11:21:47

相關問題