使用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。
代理类可以实现指定的接口类。
它具有下列方法:
1.指定接口所需要的全部方法;
2.Object类的全部方法,例如:toString(),equal()等;
无论何时调用代理对象的方法,调用处理器的invoke方法都会被调用,并想起传递方法对象和原始的调用参数;
首先,想要创建一个代理对象,需要使用代理类Proxy的newProxyInstance方法:
该方法有三个参数:
第一个参数:类加载器,可以传null
第二个参数:Class对象组,即每个元素都需要实现的接口;
第三个参数:一个调用处理器
下面为代码实例:
调用处理器
package com.model;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TraceHendler implements InvocationHandler{
/**
* 构造方法
* @param target
*/
public TraceHendler(Object target) {
super();
this.target = target;
}
private Object target;
/***
* 第一个参数arg0表示需要代理的参数
* 第二个参数arg1表示第一 个参数arg0需要实现的接口方法
* 第三个参数arg2表示的是第二个参数arg1方法的参数
*/
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
// 打印需要代理的参数
System.out.print(target);
//打印方法名
System.out.print("."+arg1.getName()+"(");
//打印参数
if(arg2!=null)
{
for(Object obj:arg2){
System.out.print(obj);
}
System.out.print(")");
System.out.println();
}
//执行public abstract int java.lang.Comparable.compareTo(java.lang.Object)方法
return arg1.invoke(target, arg2);
}
}
测试类
package com.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;
import com.model.TraceHendler;
public class ProxyTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//随机定义一个数据
Object[] objs=new Object[1000];
//遍历数组 将数组中的每个成员都设置成为代理实现ComparaTo方法
for(int i=0;i<objs.length;i++){
Integer value=i+1;
InvocationHandler handler=new TraceHendler(value);
Object proxy=Proxy.newProxyInstance(null, new Class[]{Comparable.class}, handler);
objs[i]=proxy;
}
//定义一个随机数
Integer key=new Random().nextInt(objs.length)+1;
//使用数组的二分法找到该随机数
//因为数据的二分法使用了compareTo方法,所以就会执行代理中的invoke方法进行打印
int result=Arrays.binarySearch(objs, key);
if(result>0)
System.out.println(objs[result]);
int[] newArray=new int[]{1,2,3};
int result2=Arrays.binarySearch(newArray, 2);
System.out.println(result2);
}
}
总结:感觉目前用到的地方比较少。