JavaTM 2 Platform
Standard Ed. 6

java.lang.reflect
類別 Proxy

java.lang.Object
  繼承者 java.lang.reflect.Proxy
所有已實作的介面:
Serializable

public class Proxy
extends Object
implements Serializable

Proxy 提供用於創建動態代理類別和實例的靜態方法,它還是由這些方法創建的所有動態代理類別的父級類別。

創建某一介面 Foo 的代理:

     InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 
或使用以下更簡單的方法:
     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
 

動態代理類別(以下簡稱為代理類別)是一個實作在創建類別時在運行時指定的介面列表的類別,該類別具有下面描述的行為。 代理介面 是代理類別實作的一個介面。 代理實例 是代理類別的一個實例。 每個代理實例都有一個關聯的調用處理程序 物件,它可以實作介面 InvocationHandler。通過其中一個代理介面的代理實例上的方法調用將被指派到實例的調用處理程序的 Invoke 方法,並傳遞代理實例、識別調用方法的 java.lang.reflect.Method 物件以及包含參數的 Object 型別的陣列。調用處理程序以適當的方式處理編碼的方法調用,並且它返回的結果將作為代理實例上方法調用的結果返回。

代理類別具用以下屬性:

代理實例具有以下屬性:

在多代理介面中重複的方法

當代理類別的兩個或多個介面包含一個具有相同名稱和參數簽章的方法時,代理類別的介面順序變得非常重要。在代理實例上調用重複方法 時,傳遞到調用處理程序的 Method 物件沒有必要成為其宣告類別可以從介面(通過該介面調用代理方法)的參考型別指派的物件。此限制存在的原因是,產生的代理類別中的相應方法實作無法確定它通過哪一個介面調用。因此,在代理實例上調用重複方法時,第一個介面中的方法的 Method 物件包含介面的代理類別列表中的方法(直接或通過父級介面繼承),該物件會傳遞到調用處理程序的 invoke 方法,無論該方法調用通過哪一種參考型別發生。

如果代理介面包含某一方法,它的名稱和參數簽章與 java.lang.ObjecthashCodeequalstoString 方法相同,那麼在代理實例上調用這樣的方法時,傳遞到調用處理程序的 Method 物件將使 java.lang.Object 成為其宣告類別。換句話說,java.lang.Object 公共的非最終方法理論上在所有代理介面之前,以便確定哪一個 Method 物件傳遞到調用處理程序。

還要注意,當重複方法被指派到調用處理程序時,invoke 方法只可以拋出經過檢查的異常型別,該異常型別可以使用所有 代理介面(可以通過它調用)中方法的 throws 子句指派一種異常型別。如果 invoke 方法拋出一個經過檢查的異常,該異常沒有指派給任何由一個代理介面(可以通過它調用)中的方法宣告的異常型別,那麼該代理實例上的調用將拋出一個未經檢查的 UndeclaredThrowableException。此限製表示並非所有的由傳遞到 invoke 方法的 Method 物件上調用 getExceptionTypes 返回的異常型別都可以由 invoke 方法成功拋出。

從以下版本開始:
1.3
另請參見:
InvocationHandler, 序列化表格

欄位摘要
protected  InvocationHandler h
          此代理實例的調用處理程序。
 
建構子摘要
protected Proxy(InvocationHandler h)
          使用其調用處理程序的指定值從子類別(通常為動態代理類別)建構新的 Proxy 實例。
 
方法摘要
static InvocationHandler getInvocationHandler(Object proxy)
          返回指定代理實例的調用處理程序。
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)
          返回代理類別的 java.lang.Class 物件,並向其提供類別載入器和介面陣列。
static boolean isProxyClass(Class<?> cl)
          當且僅當指定的類別通過 getProxyClass 方法或 newProxyInstance 方法動態產生為代理類別時,返回 true。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
          返回一個指定介面的代理類別實例,該介面可以將方法調用指派到指定的調用處理程序。
 
從類別 java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

欄位詳細資訊

h

protected InvocationHandler h
此代理實例的調用處理程序。

建構子詳細資訊

Proxy

protected Proxy(InvocationHandler h)
使用其調用處理程序的指定值從子類別(通常為動態代理類別)建構新的 Proxy 實例。

參數:
h - 此代理實例的調用處理程序
方法詳細資訊

getProxyClass

public static Class<?> getProxyClass(ClassLoader loader,
                                     Class<?>... interfaces)
                              throws IllegalArgumentException
返回代理類別的 java.lang.Class 物件,並向其提供類別載入器和介面陣列。該代理類別將由指定的類別載入器定義,並將實作提供的所有介面。如果類別載入器已經定義了具有相同排列介面的代理類別,那麼現有的代理類別將被返回;否則,類別載入器將動態產生並定義這些介面的代理類別。

對可以傳遞給 Proxy.getProxyClass 的參數有以下幾個限制:

如果違反了這些限制,Proxy.getProxyClass 將拋出 IllegalArgumentException。如果 interfaces 陣列參數或其任何元素為 null,則將拋出 NullPointerException

注意,指定的代理介面的順序非常重要:對介面組合相同但順序不同的代理類別的兩個請求會導致兩個不同的代理類別。

參數:
loader - 定義代理類別的類別載入器
interfaces - 代理類別要實作的介面列表
返回:
用指定的類別載入器定義的代理類別,它可以實作指定的介面
拋出:
IllegalArgumentException - 如果違反傳遞到 getProxyClass 的參數上的任何限制
NullPointerException - 如果 interfaces 陣列參數或其任何元素為 null

newProxyInstance

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
                               throws IllegalArgumentException
返回一個指定介面的代理類別實例,該介面可以將方法調用指派到指定的調用處理程序。此方法相當於:
     Proxy.getProxyClass(loader, interfaces).
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 

Proxy.newProxyInstance 拋出 IllegalArgumentException,原因與 Proxy.getProxyClass 相同。

參數:
loader - 定義代理類別的類別載入器
interfaces - 代理類別要實作的介面列表
h - 指派方法調用的調用處理程序
返回:
一個帶有代理類別的指定調用處理程序的代理實例,它由指定的類別載入器定義,並實作指定的介面
拋出:
IllegalArgumentException - 如果違反傳遞到 getProxyClass 的參數上的任何限制
NullPointerException - 如果 interfaces 陣列參數或其任何元素為 null,或如果調用處理程序 hnull

isProxyClass

public static boolean isProxyClass(Class<?> cl)
當且僅當指定的類別通過 getProxyClass 方法或 newProxyInstance 方法動態產生為代理類別時,返回 true。

此方法的可靠性對於使用它做出安全決策而言非常重要,所以此方法的實作不應僅測試相關的類別是否可以擴展 Proxy

參數:
cl - 要測試的類別
返回:
如該類別為代理類別,則為 true,否則為 false
拋出:
NullPointerException - 如果 clnull

getInvocationHandler

public static InvocationHandler getInvocationHandler(Object proxy)
                                              throws IllegalArgumentException
返回指定代理實例的調用處理程序。

參數:
proxy - 返回調用處理程序的代理實例
返回:
代理實例的調用處理程序
拋出:
IllegalArgumentException - 如果參數不是一個代理實例

JavaTM 2 Platform
Standard Ed. 6

提交錯誤或意見

版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only