|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
java.lang.Object java.lang.reflect.Proxy
public class Proxy
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
を実装しています。プロキシインタフェースの 1 つを使ったプロキシインスタンスでのメソッド呼び出しは、インスタンスの呼び出しハンドラの invoke
メソッドにディスパッチされ、呼び出されたメソッドを識別する java.lang.reflect.Method
オブジェクト、および引数を格納する Object
型の配列をプロキシインスタンスに引き渡します。呼び出しハンドラは符号化されたメソッド呼び出しを適切に処理し、呼び出しハンドラが返す結果が、プロキシインスタンスでのメソッド呼び出しの結果として返されます。
プロキシクラスには、次の特性があります。
$Proxy
」で始まるクラス名の領域をプロキシクラスのために確保しておく必要があります。
java.lang.reflect.Proxy
を継承します。
Class
オブジェクト上で getInterfaces
を呼び出した場合は、同じインタフェースのリストを含む配列が、作成時に指定された順番で返されます。 Class
オブジェクト上で getMethods
を呼び出した場合は、それらのインタフェース内のすべてのメソッドを含む Method
オブジェクトの配列が返されます。 getMethod
を呼び出した場合は、プロキシインタフェース内で目的のメソッドが検索されます。
Proxy.isProxyClass
メソッドは、Proxy.getProxyClass
によって返されたプロキシクラス、あるいは Proxy.newProxyInstance
によって返されたオブジェクトのクラスなどのプロキシクラスに引き渡された場合に true を返します。それ以外の場合は false を返します。
java.security.ProtectionDomain
は、java.lang.Object
などの、ブートストラップクラスローダによってロードされるシステムクラスの java.security.ProtectionDomain
と同じです。 プロキシクラスのコードは、信頼されたシステムコードによって生成されるためです。標準では、この保護ドメインに対して java.security.AllPermission
が与えられます。
InvocationHandler
の実装を取る 1 つの public コンストラクタがあります。リフレクション API を使って public コンストラクタにアクセスする以外に、Proxy.newInstance
メソッドを呼び出してプロキシインスタンスを生成することもできます。このメソッドは Proxy.getProxyClass
の呼び出し動作を、呼び出しハンドラを持つコンストラクタの呼び出しと結合します。
プロキシインスタンスには、次の特性があります。
proxy
プロキシインスタンス、およびその Foo
プロキシクラスによって実装されたインタフェースに対して次の式を実行すると、true が返されます。
proxy instanceof Foo
次のキャスト操作は、正常終了し、ClassCastException
はスローされません。
(Foo) proxy
Proxy.getInvocationHandler
メソッドは、その引数として渡されたプロキシインスタンスに関連する呼び出しハンドラを返します。
invoke
メソッドにディスパッチされます。
java.lang.Object
に宣言されている hashCode
、equals
または toString
呼び出しは、前述したようにインタフェースメソッド呼び出しと同じ方法で、符号化され、呼び出しハンドラの invoke
メソッドにディスパッチされます。invoke
に渡される Method
オブジェクトの宣言クラスは、java.lang.Object
です。java.lang.Object
から継承されるプロキシインスタンスのその他の public メソッドは、プロキシクラスによってオーバーライドされません。 このため、これらのメソッドの呼び出しは、java.lang.Object
のインスタンスに対する呼び出しと同様に行われます。
複数のインタフェースに、同じ名前とパラメータシグニチャーを持つメソッドが含まれる場合は、プロキシクラスのインタフェースの順番が区別されます。プロキシインスタンス上で「重複するメソッド」が呼び出された場合、呼び出しハンドラに渡される Method
オブジェクトで、プロキシメソッドの呼び出しに使用されたインタフェースの参照型から宣言クラスを割り当てることができないことがあります。このような制約が存在するのは、生成されたプロキシクラス内の対応するメソッドの実装から、その実装が呼び出されたときに使用されたインタフェースを特定できないためです。このため、プロキシインスタンス上で重複するメソッドが呼び出された場合は、メソッド呼び出しに使用された参照型にかかわりなく、プロキシクラスのインタフェースリストでそのメソッド (直接またはスーパーインタフェースから継承) を含むインタフェースのうち、最初のインタフェースのメソッドの Method
オブジェクトが呼び出しハンドラの invoke
メソッドに渡されます。
プロキシインタフェースに、java.lang.Object
の hashCode
、equals
、または toString
メソッドと同じ名前およびパラメータシグニチャーを持つメソッドが含まれる場合は、プロキシインスタンス上でそのメソッドが呼び出されると、呼び出しハンドラに渡される Method
オブジェクトの宣言クラスは java.lang.Object
になります。つまり、public で非 final である java.lang.Object
のメソッドは、呼び出しハンドラに渡す Method
オブジェクトを決定するときに、論理的にほかのプロキシインタフェースより優先されます。
重複するメソッドが呼び出しハンドラにディスパッチされた場合は、invoke
メソッドからスローできる例外の型は、チェックされる型のうち、呼び出されるすべてのプロキシインタフェースのメソッドに指定されている、throws
句の例外の型に割り当てることができるものに限定されます。invoke
メソッドが、呼び出しに使えるプロキシインタフェースの 1 つのメソッドで宣言された例外タイプのどれにも割り当てできない確認済み例外をスローした場合、確認されていない UndeclaredThrowableException
がプロキシインスタンスでの呼び出しによってスローされます。つまり、invoke
メソッドに渡された Method
オブジェクト上で、getExceptionTypes
を呼び出して例外の型を取得しても、invoke
メソッドから正常にスローされないことがあります。
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 |
フィールドの詳細 |
---|
protected InvocationHandler h
コンストラクタの詳細 |
---|
protected Proxy(InvocationHandler h)
Proxy
インスタンスを構築します。
h
- このプロキシインスタンスの呼び出しハンドラメソッドの詳細 |
---|
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException
java.lang.Class
オブジェクトを返します。プロキシクラスは指定されたクラスローダーにより定義され、指定されたインタフェースをすべて実装します。インタフェースの同じ順列のプロキシクラスがすでにクラスローダーにより定義されている場合、既存のプロキシクラスが返されます。 そうでない場合は、これらのインタフェースのプロキシクラスが動的に生成され、クラスローダーにより定義されます。
Proxy.getProxyClass
に渡すことのできるパラメータには、いくつかの制約があります。
interfaces
配列のすべての Class
オブジェクトは、クラスまたはプリミティブ型ではなくインタフェースを表していなければならない
interfaces
配列の複数の要素が、同じ Class
オブジェクトを参照してはならない
cl
、各インタフェースが i
の場合は、次の式が true でなければならない
Class.forName(i.getName(), false, cl) == i
interfaces
配列のサイズは 65535 を超えてはならない
これらの制約に対して違反が発生した場合は、Proxy.getProxyClass
によって IllegalArgumentException
がスローされます。interfaces
配列の引数または要素が null
の場合は、NullPointerException
がスローされます。
プロキシインタフェースは、順番が区別されます。プロキシクラスを 2 回要求したときに、インタフェースの組み合わせが同じで順番が異なる場合は、2 つの異なるプロキシクラスが作成されます。
loader
- プロキシクラスを定義するクラスローダーinterfaces
- プロキシクラスが実装するインタフェースのリスト
IllegalArgumentException
- getProxyClass
に引き渡されるパラメータに関する制約のどれかが守られなかった場合
NullPointerException
- interfaces
配列の引数またはその要素のどれかが null
の場合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
は、Proxy.getProxyClass
の場合と同じ理由で、IllegalArgumentException
をスローします。
loader
- プロキシクラスを定義するクラスローダーinterfaces
- プロキシクラスが実装するインタフェースのリストh
- メソッド呼び出しのディスパッチ先の呼び出しハンドラ
IllegalArgumentException
- getProxyClass
に引き渡されるパラメータに関する制約のどれかが守られなかった場合
NullPointerException
- interfaces
配列の引数またはその要素のどれかが null
の場合、または呼び出しハンドラ h
が null
の場合public static boolean isProxyClass(Class<?> cl)
getProxyClass
メソッドまたは newProxyInstance
メソッドを使って動的に生成されてプロキシクラスとなる場合にだけ、true を返します。
このメソッドの信頼性は、このメソッドによってセキュリティ保護をできるかどうかを決定する際に重要です。このため、当該クラスが Proxy
を拡張するかどうかをこのメソッドの実装でテストするだけでは十分とは言えません。
cl
- テストするクラス
true
、そうでない場合は false
NullPointerException
- cl
が null
の場合public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException
proxy
- 呼び出しハンドラを返すプロキシインスタンス
IllegalArgumentException
- 引数がプロキシインスタンスではない場合
|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。