public class Proxy
extends Object
implements Serializable
java.lang.Object | |
↳ | java.lang.reflect.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 });or more simply:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler);
动态代理类 (以下简称为代理类 )是一个类,它实现了创建类时在运行时指定的接口列表,其行为如下所述。 代理接口是由代理类实现的接口。 代理实例是代理类的实例。 每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler
。 通过其代理接口之一上的代理实例的方法调用将被分派到invoke
实例的调用处理程序的方法,并传递代理实例,一个java.lang.reflect.Method
对象识别的方法被调用,和类型的数组Object
包含参数。 调用处理程序适当地处理编码的方法调用,并且返回的结果将作为代理实例上方法调用的结果返回。
代理类具有以下属性:
"$Proxy"
should be, however, reserved for proxy classes. java.lang.reflect.Proxy
. getInterfaces
on its Class
object will return an array containing the same list of interfaces (in the order specified at its creation), invoking getMethods
on its Class
object will return an array of 方法
objects that include all of the methods in those interfaces, and invoking getMethod
will find methods in the proxy interfaces as would be expected. Proxy.isProxyClass
method will return true if it is passed a proxy class-- a class returned by Proxy.getProxyClass
or the class of an object returned by Proxy.newProxyInstance
-- and false otherwise. java.security.ProtectionDomain
of a proxy class is the same as that of system classes loaded by the bootstrap class loader, such as java.lang.Object
, because the code for a proxy class is generated by trusted system code. This protection domain will typically be granted java.security.AllPermission
. InvocationHandler
, to set the invocation handler for a proxy instance. Rather than having to use the reflection API to access the public constructor, a proxy instance can be also be created by calling the Proxy.newProxyInstance
method, which combines the actions of calling Proxy.getProxyClass
with invoking the constructor with an invocation handler. 代理实例具有以下属性:
proxy
and one of the interfaces implemented by its proxy class Foo
, the following expression will return true:
proxy instanceof Foo
and the following cast operation will succeed (rather than throwing a ClassCastException
):
(Foo) proxy
Proxy.getInvocationHandler
method will return the invocation handler associated with the proxy instance passed as its argument. invoke
method as described in the documentation for that method. hashCode
, equals
, or toString
methods declared in java.lang.Object
on a proxy instance will be encoded and dispatched to the invocation handler's invoke
method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the 方法
object passed to invoke
will be java.lang.Object
. Other public methods of a proxy instance inherited from java.lang.Object
are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object
. 当代理类的两个或多个接口包含具有相同名称和参数签名的方法时,代理类的接口顺序变得很重要。 当这样的重复的方法是在一个代理实例调用时, 方法
传递给调用处理程序对象将不一定是其声明类是从该代理的方法是通过调用接口的引用类型分配的一个。 存在此限制是因为生成的代理类中的相应方法实现无法确定通过哪个接口调用它。 因此,当重复的方法是在代理实例调用时, 方法
对象为接口的代理类的列表包含方法(直接或继承通过超接口)中最重要的接口中的方法传递给调用处理程序的invoke
方法,而与方法调用发生的引用类型无关。
如果代理接口包含具有相同的名称和参数签名的方法hashCode
, equals
,或toString
的方法java.lang.Object
,当这种方法在代理实例调用时, 方法
传递到调用处理程序对象将java.lang.Object
作为其宣布课程。 换句话说, java.lang.Object
的公共非最终方法在逻辑上位于所有代理接口之前,以确定哪个方法
对象传递给调用处理程序。
另请注意,将重复方法分派给调用处理程序时, invoke
方法可能只会引发已检查的异常类型,这些异常类型可分配给该方法的throws
子句中的一个异常类型, throws
在可调用的所有代理接口中通过。 如果invoke
方法抛出一个检查的异常,该异常不可分配给该方法声明的任何异常类型,并且该异常类型可以通过其中一个代理接口进行调用,则未UndeclaredThrowableException
将由代理实例上的调用引发。 此限制意味着,并非所有通过调用返回的异常类型的getExceptionTypes
的上方法
传递给对象invoke
方法一定可以成功地抛出invoke
方法。
也可以看看:
Fields |
|
---|---|
protected InvocationHandler |
h 此代理实例的调用处理程序。 |
Protected constructors |
|
---|---|
Proxy(InvocationHandler h) 从其子类(通常为动态代理类)构造一个新的 |
Public methods |
|
---|---|
static InvocationHandler |
getInvocationHandler(Object proxy) 返回指定代理实例的调用处理程序。 |
static Class<?> |
getProxyClass(ClassLoader loader, Class...<?> interfaces) 给定类加载器和一组接口,返回代理类的 |
static boolean |
isProxyClass(Class<?> cl) 当且仅当使用 |
static Object |
newProxyInstance(ClassLoader loader, Class[]<?> interfaces, InvocationHandler h) 返回指定接口的代理类实例,该接口将方法调用分派给指定的调用处理程序。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
Proxy (InvocationHandler h)
从其子类(通常是动态代理类)构造一个新的 Proxy
实例,并为其调用处理程序指定一个值。
Parameters | |
---|---|
h |
InvocationHandler : the invocation handler for this proxy instance |
InvocationHandler getInvocationHandler (Object proxy)
返回指定代理实例的调用处理程序。
Parameters | |
---|---|
proxy |
Object : the proxy instance to return the invocation handler for |
Returns | |
---|---|
InvocationHandler |
the invocation handler for the proxy instance |
Throws | |
---|---|
IllegalArgumentException |
if the argument is not a proxy instance |
Class<?> getProxyClass (ClassLoader loader, Class...<?> interfaces)
给定一个类加载器和一组接口,返回代理类的java.lang.Class
对象。 代理类将由指定的类加载器定义,并将实现所有提供的接口。 如果类加载器已经定义了相同接口排列的代理类,则将返回现有的代理类; 否则,这些接口的代理类将被动态生成并由类加载器定义。
对可能传递给 Proxy.getProxyClass
的参数有几个限制:
Class
objects in the interfaces
array must represent interfaces, not classes or primitive types. interfaces
array may refer to identical Class
objects. cl
and every interface i
, the following expression must be true: Class.forName(i.getName(), false, cl) == i
interfaces
array must not exceed 65535. 如果违反了这些限制,则Proxy.getProxyClass
将抛出IllegalArgumentException
。 如果interfaces
数组参数或其任何元素为null
,则会引发NullPointerException
。
请注意,指定的代理接口的顺序非常重要:对具有相同接口组合但具有不同顺序的代理类的两个请求将导致两个不同的代理类。
Parameters | |
---|---|
loader |
ClassLoader : the class loader to define the proxy class |
interfaces |
Class : the list of interfaces for the proxy class to implement |
Returns | |
---|---|
Class<?> |
a proxy class that is defined in the specified class loader and that implements the specified interfaces |
Throws | |
---|---|
IllegalArgumentException |
if any of the restrictions on the parameters that may be passed to getProxyClass are violated |
NullPointerException |
if the interfaces array argument or any of its elements are null |
boolean isProxyClass (Class<?> cl)
当且仅当使用 getProxyClass
方法或 newProxyInstance
方法将指定的类动态生成为代理类时才返回true。
这种方法的可靠性对于使用它来做出安全决策的能力很重要,因此它的实现不应该仅仅测试有问题的类是否扩展了 Proxy
。
Parameters | |
---|---|
cl |
Class : the class to test |
Returns | |
---|---|
boolean |
true if the class is a proxy class and false otherwise |
Throws | |
---|---|
NullPointerException |
if cl is null |
Object newProxyInstance (ClassLoader loader, Class[]<?> interfaces, InvocationHandler h)
返回指定接口的代理类实例,该接口将方法调用分派给指定的调用处理程序。 这种方法相当于:
Proxy.getProxyClass(loader, interfaces). getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler });
Proxy.newProxyInstance
抛出 IllegalArgumentException
为同样的原因 Proxy.getProxyClass
一样。
Parameters | |
---|---|
loader |
ClassLoader : the class loader to define the proxy class |
interfaces |
Class : the list of interfaces for the proxy class to implement |
h |
InvocationHandler : the invocation handler to dispatch method invocations to |
Returns | |
---|---|
Object |
a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces |
Throws | |
---|---|
IllegalArgumentException |
if any of the restrictions on the parameters that may be passed to getProxyClass are violated |
NullPointerException |
if the interfaces array argument or any of its elements are null , or if the invocation handler, h , is null |