Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。代理接口是代理类实现的一个接口。代理实例是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序对象,它可以实现接口InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的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.AllPermission
。 - 每个代理类都有一个可以带一个参数(接口
InvocationHandler
的实现)的公共构造方法,用于设置代理实例的调用处理程序。并非必须使用反射 API 才能访问公共构造方法,通过调用Proxy.newInstance
方法(将调用Proxy.getProxyClass
的操作和调用带有调用处理程序的构造方法结合在一起)也可以创建代理实例。
创建动态类及查看其方法列表信息。代码如下:
package com.itheima.shipin.daili;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Collections;
public class ProxyTest {
public static void main(String[] args) {
//返回代理类的Class对象
Class clazzProxy = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
System.out.println("构造方法");
//对象所表示的类的所有公共构造方法。
Constructor[] constructors = clazzProxy.getConstructors();
for (Constructor constructor : constructors) {
StringBuilder name = new StringBuilder(constructor.getName()); //
// System.out.println(name);
name.append("(");
Class[] clazzparams = constructor.getParameterTypes();
for (Class param : clazzparams) { //构造方法的形参类型
System.out.println(param.getName());
name.append(param.getName());
}
name.append(")");
System.out.println(name);
}
// System.out.println(clazzProxy.getName());
System.out.println("所有方法");
//查看其所有方法
Method[] methods = clazzProxy.getMethods();
for (Method method : methods) {
StringBuilder name = new StringBuilder(method.getName());
// System.out.println(name);
name.append("(");
Class[] clazzparams = method.getParameterTypes();
for (Class param : clazzparams) {
// System.out.println(param.getName());
name.append(param.getName()).append(",");
}
if (clazzparams != null && clazzparams.length != 0) {
name.deleteCharAt(name.length() - 1);
}
name.append(")");
System.out.println(name);
}
}
}
运行结果
java.lang.reflect.InvocationHandler
$Proxy0(java.lang.reflect.InvocationHandler)
add(java.lang.Object)
hashCode()
clear()
equals(java.lang.Object)
toString()
contains(java.lang.Object)
isEmpty()
addAll(java.util.Collection)
iterator()
size()
toArray([Ljava.lang.Object;)
toArray()
remove(java.lang.Object)
containsAll(java.util.Collection)
removeAll(java.util.Collection)
retainAll(java.util.Collection)
isProxyClass(java.lang.Class)
getProxyClass(java.lang.ClassLoader,[Ljava.lang.Class;)
getInvocationHandler(java.lang.Object)
newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler)
wait()
wait(long,int)
wait(long)
getClass()
notify()
notifyAll()