6.5 代理

利用代理可以在运行时创建一个实现了一组给定接口的新类。

6.5.1何时使用代理

假设由一个表示接口的Class对象(可能只包含一个接口),它的确切类型在编译时无法知道。要想构造一个实现这些接口的类,就需要使用newInstance方法或反射找出这个类的构造器。但是不能实例化一个接口,需要在程序处于运行状态时定义一个新类。

代理类可以在运行时创建全新的类。

调用处理器,是实现了InvocationHandler接口的类对象。

6.5.2创建代理对象

要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法。这个方法有三个参数:

  • 类加载器;
  • 一个Class对象数组,每个元素都是需要实现的接口。
  • 一个调用处理器。

为什么使用代理?

  • 路由对远程服务器方法的调用。
  • 在程序运行期间,将用户事件与动作关联起来。
  • 调试,跟踪方法用。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;

public class ProxyTest {
   public static void main(String[] args) {
       Object [] elments = new Object[10];
       for (int i = 0; i < elments.length; i++) {
           Integer value = i + 1;
           InvocationHandler invocationHandler = new TraceHandler(value);
           Object proxy = Proxy.newProxyInstance(null,new Class[]{Comparable.class}, invocationHandler);
           elments[i] = proxy;
       }
       Integer key = new Random().nextInt(elments.length) + 1;

       int result = Arrays.binarySearch(elments,key);
       System.out.println("result " + result);
       if (result >= 0) System.out.println(elments[result]);
   }
}
class TraceHandler implements InvocationHandler{

   private Object target;

   public TraceHandler(Object o){
       target = o;
   }
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       System.out.print(target);
       System.out.print("." + method.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 method.invoke(target,args);
   }
}

println方法调用代理对象的toString。

6.5.3代理的特性

代理类是在运行过程中创建的。而一旦创建就变成了常规类,与虚拟机中的其它类没区别。

所有的代理类都扩展与Proxy类。一个代理类只有一个实例域–调用处理器,它定义在Proxy的超类中。未来履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器。如TraceHandler

使用getProxyClass方法获得这个类。

Class proxyClass = Proxy.getProxyClass(null,interfaces)

代理类一定是public final的。

//是否是一个代理类
Proxy.gisProxyClass(Class<?> c1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值