黑马程序员技术交流社区

标题: java的代理问题二? [打印本页]

作者: lonely_zb    时间: 2013-9-7 17:38
标题: java的代理问题二?
java生成代理类的方法有:

Proxy.newProxyInstance(ClassLoader c1,Class[] c2  InvocationHandler c3 );


可是我记得还有这样一个方法:

Class  clazzProxy =  Proxy.getProxyClass(ClassLoader c1,Class c2);

也可以生成一个代理类啊,意思是Proxy.getProxyClass生成的是代理类的字节码,只是代理类的class类型吗?


请问这2个方法有什么区别呢?





作者: gulup    时间: 2013-9-7 18:07
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
          返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
getProxyClass(ClassLoader loader, Class<?>... interfaces)
          返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。
API写得已经够清晰了
作者: 张聪珉    时间: 2013-9-7 18:17
上面的方法是生成代理类的实例对象,下面的方法是生成代理类在内存当中字节码文件也是一个对象,这个对象是一份字节码文件,想不用上面方法创建代理类的实例对象,需要通过反射获得构造方法,反射获得的构造方法只有一个,高新里面张老师证明了这个过程,获得的构造方法接收一个InvocationHandler接口实现类的实例对象,再用构造方法产生生成代理类的实例对象了,上面方法是开发中常用的写代码方式,建议记下来
作者: 张歆明    时间: 2013-9-7 18:36
楼主这个问题问的好

实际上 你要是看了Proxy的源码之后,newProxyInstance方法是首先调用getProxyClass方法获取动态代理类的字节码对象,有了字节码对象Class之后,楼主,是不是就可以使用Class对象的Constructor相关的方法来创建这个Class对象对应类的实例了?

因此  newProxyInstance方法中也就是这么做的

我整理了一下  你看看有帮助没
源码如下:
  1. public class Proxy implements java.io.Serializable {
  2.   //...
  3.   //对Proxy的动态代理类,由于只有一个构造方法,并且方法的参数只有一个
  4. //InvocationHandler类型的,所以这里面就直接把这个形参固定住,不在要求用
  5. //户关联形参
  6. private final static Class[] constructorParams = {InvocationHandler.class};
  7. //...
  8. public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
  9.         if (h == null) {
  10.                 throw new NullPointerException();
  11.         }
  12.         Class cl = getProxyClass(loader, interfaces);
  13.         try {
  14.                 Constructor cons = cl.getConstructor(constructorParams);
  15.                 return (Object) cons.newInstance(new Object[] { h });
  16.         } catch (NoSuchMethodException e) {
  17.                 throw new InternalError(e.toString());
  18.         } catch (IllegalAccessException e) {
  19.                 throw new InternalError(e.toString());
  20.         } catch (InstantiationException e) {
  21.                 throw new InternalError(e.toString());
  22.         } catch (InvocationTargetException e) {
  23.                 throw new InternalError(e.toString());
  24.         }
  25. }
  26. //...
  27. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2