Proxy 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
Proxy 提供靜態方法來建立動態代理類別與實例,並且是所有由這些方法建立的動態代理類別的超類別。
[Android.Runtime.Register("java/lang/reflect/Proxy", DoNotGenerateAcw=true)]
public class Proxy : Java.Lang.Object, IDisposable, Java.IO.ISerializable
[<Android.Runtime.Register("java/lang/reflect/Proxy", DoNotGenerateAcw=true)>]
type Proxy = class
inherit Object
interface ISerializable
interface IJavaObject
interface IDisposable
interface IJavaPeerable
- 繼承
- 屬性
- 實作
備註
Proxy 提供靜態方法來建立動態代理類別與實例,並且是所有由這些方法建立的動態代理類別的超類別。
要為某個介面 Foo建立代理:
InvocationHandler handler = new MyInvocationHandler(...);
Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
newInstance(handler);
或者更簡單地說:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class<?>[] { Foo.class },
handler);
動態代理類別(以下簡稱代理類別)是一種在建立該類別時,實作執行時指定的介面清單的類別,行為如下所述。
代理介面是由代理類別實作的介面。
代理實例是代理類別的實例。
每個代理實例都有一個對應的 調用處理物件 ,該物件實作介面 InvocationHandler。 透過代理實例的代理介面呼叫方法,會被派遣到 InvocationHandler#invoke invoke 該實例的呼叫處理器的方法,並傳遞代理實例、 java.lang.reflect.Method 識別被呼叫方法的物件,以及包含參數的陣列 Object 。 呼叫處理程序會適當處理編碼的方法呼叫,而其回傳的結果將作為代理實例中方法呼叫的結果回傳。
代理類別具有以下特性:
<ul><li>代理類別是 <em>public、final,且非抽象</em> ,前提是所有代理介面都是公開的。</李>
<代理>類別是<>非公開的,最終的,且如果代理介面中有任何非公開,則非抽象<或抽象>類別。</李>
<li>代理類別的無限定名稱未被指定。 不過,以字串 "$Proxy" 開頭的類別名稱空間應保留給代理類別。
<li>代理類擴展 java.lang.reflect.Proxy。
<li>代理類別會完全實作建立時指定的介面,順序相同。
<li>如果代理類別實作非公開介面,則該介面將與該介面在同一封包中定義。 否則,代理類別的封包也未被指定。 請注意,封裝不會阻止代理類別在執行時成功在特定套件中被定義,同一個類別載入器與同一套件中特定簽章者已定義的類別也不會。
<由於>代理類別實作了建立時所指定的所有介面, getInterfaces 呼叫其 Class 物件時會回傳包含相同介面清單的陣列(依創建時指定的順序),呼叫 getMethods 物件 Class 時會回傳包含該介面中所有方法的物件陣列 Method ,呼叫 getMethod 則會如預期般找到代理介面中的方法。
<li>Proxy#isProxyClass Proxy.isProxyClass 如果方法被傳遞代理類別——由 回傳Proxy.getProxyClass的 類別或由 返回Proxy.newProxyInstance的物件類別——則回傳為真,否則為假。
<li>代理類別的 The java.security.ProtectionDomain 與由引導類別載入器的系統類別相同, java.lang.Object例如 ,因為代理類別的程式碼是由受信任的系統程式碼產生的。 這個保護領域通常會被授予 java.security.AllPermission。
<li>每個代理類別有一個公開建構子,該建構子會取一個參數,即介面 InvocationHandler的實作,來設定代理實例的調用處理器。 與其使用反射 API 來存取公開建構子,也可以透過呼叫 Proxy#newProxyInstance Proxy.newProxyInstance 方法建立代理實例,該方法結合呼叫 Proxy#getProxyClass Proxy.getProxyClass 與調用建構子的操作,並搭配調用處理器。
</ul>
代理實例具有以下特性:
<ul><li>給定一個代理實例 proxy 及其代理類別 Foo實作的介面,以下表達式將回傳為真:
{@code proxy instanceof Foo}
以下的鑄造運算將成功(而非拋出):ClassCastException
{@code (Foo) proxy}
<li>每個代理實例都有一個對應的調用處理器,即傳給其建構者的處理器。 靜態 Proxy#getInvocationHandler Proxy.getInvocationHandler 方法會回傳與代理實例相關的呼叫處理器,作為其參數傳遞。
<li>代理實例上的介面方法調用會依照該方法文件中所述,編碼並派遣到呼叫處理器的方法 InvocationHandler#invoke invoke 。
<li>代理實例中宣告的 hashCode 、 equals、 toString 或方法的呼叫java.lang.Object,將以與介面方法呼叫相同的方式編碼並派發到呼叫處理器的方法invoke,如上所述。 傳遞給物件的Method宣告類別將為 invoke。java.lang.Object 繼承自 java.lang.Object 代理實例的其他公開方法不會被代理類別覆蓋,因此這些方法的調用行為與 的 java.lang.Object實例相同。
</ul>
<h3>方法在多個代理介面<中重複/h3>
當代理類別的兩個或以上介面包含名稱與參數簽章相同的方法時,代理類別介面的順序變得非常重要。 當在代理實例上呼叫此類 重複方法 時,傳給呼叫處理器的 Method 物件不一定是可從代理方法所透過的介面參考型態指派的宣告類別。 此限制存在於產生代理類別中對應的方法實作無法判斷其被呼叫的介面。 因此,當代理實例呼叫重複方法時, Method 代理類別介面列表中包含該方法(直接或透過超介面繼承)的最前介面中方法的物件,會傳遞給呼叫處理器的方法 invoke ,無論呼叫是透過何種參考類型進行。
如果代理介面包含與 、 或 hashCode 的方法名稱相同且參數簽章equalstoString相同的方法,當該方法在代理實例中被呼叫時,java.lang.Object傳給呼叫處理器的物件將擁有 Method 作為其宣告java.lang.Object類別。 換句話說,公有且非最終 java.lang.Object 的方法邏輯上會先於所有代理介面,決定要傳遞給 Method 呼叫處理器的物件。
另外請注意,當重複方法被派遣到呼叫處理程序時,該 invoke 方法只能拋出可指派給該方法子句中可指派到某一例外類型的 throws 已檢查異常類型 ,並透過 所有可透過的代理介面中。 如果 invoke 方法拋出一個檢查過的例外,且該異常無法指派到該方法在可呼叫的代理介面中宣告的任何例外類型,那麼在代理實例的呼叫中,會拋出一個未被檢查的 UndeclaredThrowableException 例外。 此限制意味著並非所有透過呼叫 getExceptionTypes 傳送 Method 給 invoke 方法的物件所回傳的例外類型都能被 invoke 方法成功拋出。
在 1.3 版本中加入。
Java 文件 java.lang.reflect.Proxy。
本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。
建構函式
| 名稱 | Description |
|---|---|
| Proxy(IInvocationHandler) |
從子類別(通常是動態代理類別)構造一個新 |
| Proxy(IntPtr, JniHandleOwnership) |
用於建立 JNI 物件受管理表示的建構器;由執行時呼叫。 |
屬性
| 名稱 | Description |
|---|---|
| Class |
回傳此 |
| H |
這個代理實例的呼叫處理器。 |
| Handle |
底層 Android 實例的帳號。 (繼承來源 Object) |
| JniIdentityHashCode |
取得由互通執行時指派給此 Java 對等端的身份雜湊碼。 (繼承來源 Object) |
| JniManagedPeerState |
|
| JniPeerMembers |
|
| PeerReference |
取得這個 Java 節點的 JNI 物件參考。 (繼承來源 Object) |
| ThresholdClass |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
| ThresholdType |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
方法
| 名稱 | Description |
|---|---|
| Clone() |
建立並回傳此物件的副本。 (繼承來源 Object) |
| Construct(JniObjectReference, JniObjectReferenceOptions) |
|
| Dispose() |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| Dispose(Boolean) |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| DisposeUnlessReferenced() |
|
| Equals(Object) |
|
| Equals(Object) |
表示是否有其他物體「等同」於此物。 (繼承來源 Object) |
| GetHashCode() |
回傳物件的雜湊碼值。 (繼承來源 Object) |
| GetInvocationHandler(Object) |
回傳指定代理實例的呼叫處理器。 |
| GetProxyClass(ClassLoader, Class[]) |
回傳 |
| IsProxyClass(Class) |
當且僅當指定類別是用 |
| JavaFinalize() |
已淘汰.
當垃圾回收判定該物件不再有相關參考時,由垃圾回收器呼叫。 (繼承來源 Object) |
| NewProxyInstance(ClassLoader, Class[], IInvocationHandler) |
回傳指定介面的代理類別實例,該代理類別將方法調用調用調派至指定的調用處理器。 |
| Notify() |
喚醒一個正在該物件監視器上等待的執行緒。 (繼承來源 Object) |
| NotifyAll() |
喚醒所有等待該物件監視器的執行緒。 (繼承來源 Object) |
| SetHandle(IntPtr, JniHandleOwnership) |
設定 Handle 屬性。 (繼承來源 Object) |
| SetPeerReference(JniObjectReference, JniObjectReferenceOptions) |
|
| ToArray<T>() |
從這個 Java 陣列包裝器建立一個受管理陣列。 (繼承來源 Object) |
| ToString() |
回傳物件的字串表示。 (繼承來源 Object) |
| UnregisterFromRuntime() |
將此 Java 節點從互通執行時中取消註冊。 (繼承來源 Object) |
| Wait() |
導致目前執行緒等待被喚醒,通常是透過 <em>通知</><em 或 em>中斷</em> 來喚醒。 (繼承來源 Object) |
| Wait(Int64, Int32) |
會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。 (繼承來源 Object) |
| Wait(Int64) |
會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。 (繼承來源 Object) |
明確介面實作
| 名稱 | Description |
|---|---|
| IJavaPeerable.Disposed() |
|
| IJavaPeerable.Finalized() |
|
| IJavaPeerable.JniObjectReferenceControlBlock |
|
| IJavaPeerable.SetJniIdentityHashCode(Int32) |
|
| IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
|
| IJavaPeerable.SetPeerReference(JniObjectReference) |
|
| IJavaPeerable.UnregisterFromRuntime() |
|
擴充方法
| 名稱 | Description |
|---|---|
| GetJniTypeName(IJavaPeerable) |
取得實例 |
| JavaAs<TResult>(IJavaPeerable) |
試著強制 |
| JavaCast<TResult>(IJavaObject) |
執行 Android 執行時檢查型別轉換。 |
| JavaCast<TResult>(IJavaObject) |
|
| TryJavaCast<TResult>(IJavaPeerable, TResult) |
試著強制 |