1.利用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。
2.调用处理器是实现了InvacationHandler接口的类对象。
3.无论何时调用代理对象的方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数。调用处理器必须给出处理调用的方式。
4.想要创建一个代理对象,需要使用Proxy类的newProxyInstance方法。
该方法的三个参数:
a.一个类加载器
b.一个Class对象数组
c.一个调用处理器。
5.无论何时用Proxy调用某个方法,这个方法的名字和参数就会打印出来,之后再用value调用它。
6.代理类实在程序运行时创建的,一旦被创建,就变成了常规类,与虚拟机中的任何其他类没有什么区别。
7.所有的代理类都扩展于Proxy类。一个代理类只有一个实例域即调用处理器,它定义在Proxy的超类中。
8.为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。
9.所有的代理类都覆盖了Object类中的方法toString、hashCode和equals。Object类中的其他方法没有被重新定义。
10.没有定义代理类的名字,Sun虚拟机中的Proxy类将生产一个以字符串$Proxy开头的类名。
11.对于特定的类加载器和预设的一组接口来说,只能有一个代理类。
12.代理类一定是public和final的。
13.可以通过调用Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类。
实例代码
测试类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Random; public class test { public static void main(String[] args) { Object[] ele = new Object[1000]; for(int i = 0;i < ele.length;i++) { Integer value = i + 1; InvocationHandler handler = new TraceHandler(value); Object proxy = Proxy.newProxyInstance(null, new Class[]{Comparable.class}, handler); ele[i] = proxy; } Integer key = new Random().nextInt(ele.length) + 1; int result = Arrays.binarySearch(ele, key); if(result >= 0) System.out.println(ele[result]); } }
功能类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TraceHandler implements InvocationHandler { private Object target; public TraceHandler(Object t) { target = t; } public Object invoke(Object proxy,Method m,Object[] args) throws Throwable { System.out.print(target); System.out.print("." + m.getName() + "("); if(args != null) { for(int i = 0;i < args.length;i++) { System.out.print(args[i]); if(i < args.length - 1) System.out.print(","); } } System.out.println(")"); return m.invoke(target,args); } }
原文地址:http://blog.csdn.net/zhurui_idea/article/details/44887657