代理
提供用于创建动态代理的静态方法类和实例,它也是所有类的超类由这些方法创建的动态代理类。为某个接口创建代理Foo公司
:
调用处理程序=新的MyInvocationHandler(…);类别<?>proxyClass=代理.getProxyClass(Foo.class.getClassLoader(),Foo.cass);Foo f=(Foo)proxyClass.getConstructor(InvocationHandler.class)。newInstance(处理程序);
或者更简单地说:Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),新类<?>[]{Foo.class},处理程序);
A类动态代理类(简称为代理人班下面)是一个实现接口列表的类在创建类时在运行时指定,行为为如下所述。A类代理接口是这样一个实现的接口吗通过代理类。A类代理实例是代理类的实例。每个代理实例都有一个关联的调用处理程序对象,它实现接口调用处理程序
。通过代理实例之一对代理实例进行的方法调用接口将发送到援引
实例调用处理程序的方法,传递代理实例,ajava.lang.reflect。方法
物体识别调用的方法和类型的数组对象
包含参数。调用处理程序处理适当的编码方法调用及其结果返回值将作为对的方法调用的结果返回代理实例。
代理类具有以下属性:
- 代理类是公开、最终且非抽象如果所有代理接口都是公共的。
- 代理类是非公开、最终且非抽象如果任何代理接口都是非公共的。
- 代理类的非限定名称未指定。空间以字符串开头的类名的
“$代理”
但是,应该为代理类保留。 - 代理类扩展
java.lang.reflect。代理
。 - 代理类完全实现在其以相同的顺序创建。
- 如果代理类实现了非公共接口,那么它将在与该接口相同的包中定义。否则代理类的包也未指定。注意这个包密封不会阻止成功定义代理类在运行时的特定包中,类也不会由相同的类装入器和具有特定签署人。
- 因为代理类实现了在它的创建,调用
获取接口
在其上等级
对象将返回包含相同接口列表(按创建时指定的顺序),调用获取方法
在其上等级
对象将返回一组方法
包含所有这些接口中的方法,并调用获取方法
将按预期在代理接口中查找方法。 - 这个
代理.isProxyClass
方法将如果传递给代理类,则返回true代理.getProxyClass
或由返回的对象的类代理.newProxyInstance
--否则为假。 - 这个
java.security。保护域
代理类的与bootstrap类加载的系统类相同装载机,例如java.lang.Object(java.lang.对象)
,因为代理类由受信任的系统代码生成。这种保护域通常会被授予java.security。所有权限
。 - 每个代理类都有一个接受一个参数的公共构造函数,接口的实现
调用处理程序
,设置代理实例的调用处理程序。而不是使用用于访问公共构造函数(代理实例)的反射API也可以通过调用代理.newProxyInstance
方法,它组合了调用代理.getProxyClass
调用带有调用处理程序的构造函数。
代理实例具有以下属性:
- 给定一个代理实例
代理人
和其中一个由其代理类实现的接口Foo公司
,的以下表达式将返回true:
Foo的代理实例
下面的投射操作将成功(而不是抛掷一类Cast异常
):
(Foo)代理
- 每个代理实例都有一个关联的调用处理程序它被传递给了构造函数。静电
代理.getInvocationHandler
方法将返回与代理实例关联的调用处理程序作为其论点通过。 - 代理实例上的接口方法调用将是编码并发送到调用处理程序的
援引
方法,如该方法的文档。 - 调用
哈希代码
,等于
,或toString(字符串)
中声明的方法java.lang.Object(java.lang.对象)
将对代理实例进行编码调度到调用处理程序的援引
中的方法以与接口方法调用相同的方式进行编码,并且发送,如上所述。的声明类方法
对象传递给援引
将java.lang.Object(java.lang.对象)
.代理的其他公共方法实例继承自java.lang.Object(java.lang.对象)
不是被代理类覆盖,因此这些方法的调用行为正常就像他们在java.lang.Object(java.lang.对象)
。
在多个代理接口中重复的方法
当代理类的两个或多个接口包含具有相同的名称和参数签名,代理类的顺序接口变得重要。当这样一个重复方法在代理实例上调用方法
传递的对象调用处理程序不一定是声明类可从接口的引用类型赋值代理的方法是通过调用的。存在此限制因为生成的代理中对应的方法实现类无法确定它是通过哪个接口调用的。因此,当在代理实例上调用重复方法时,这个方法
最前面接口中方法的对象包含方法(直接或通过超级接口)在代理类的接口列表中传递给调用处理程序的援引
方法,而不管发生方法调用的引用类型。
如果代理接口包含具有相同名称和参数签名作为哈希代码
,等于
,或toString(字符串)
方法java.lang.Object(java.lang.对象)
,当在代理实例上调用此类方法时方法
传递给调用处理程序的对象将具有java.lang.Object(java.lang.对象)
作为其声明类。换句话说,公共非最终方法java.lang.Object(java.lang.对象)
在逻辑上位于所有代理接口之前,用于确定哪一个方法
对象传递给调用处理程序。
还请注意,当将重复方法发送到调用处理程序援引
方法只能引发可分配给其中一个异常的选中异常类型中的类型投掷
方法的子句全部的属于可以通过其调用的代理接口。如果援引
方法抛出一个未检查的异常可分配给one中方法声明的任何异常类型可以通过代理接口调用它,然后未选中未声明ThrowableException
将被抛出对代理实例的调用。这一限制意味着不通过调用返回的所有异常类型获取异常类型
上方法
对象传递给援引
方法必须引发通过援引
方法。