黑马程序员技术交流社区

标题: 代理 [打印本页]

作者: 奔跑的二叉树    时间: 2013-9-22 00:03
标题: 代理
本帖最后由 杨增坤 于 2013-9-22 21:33 编辑
  1. package cn.os.du;
  2. import java.lang.reflect.*;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. public class ProxyTest {

  6.         public static void main(String[] args) throws Exception
  7.         {
  8.                 Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
  9.                 System.out.println(clazzProxy1.getName());
  10.                 System.out.println("---------------begin constructors list------------");
  11.                 Constructor[] constructors=clazzProxy1.getConstructors();
  12.                 for(Constructor constructor:constructors)
  13.                 {
  14.                                 String name=constructor.getName();
  15.                                 StringBuilder sBuilder=new StringBuilder(name);
  16.                                 sBuilder.append('(');
  17.                                 Class[] clazzParams=constructor.getParameterTypes();
  18.                                 for(Class clazzParam:clazzParams)
  19.                                 {
  20.                                         sBuilder.append(clazzParam.getName()).append(',');
  21.                                        
  22.                                 }
  23.                                 if(clazzParams!=null && clazzParams.length!=0)
  24.                                         sBuilder.deleteCharAt(sBuilder.length()-1);
  25.                                 sBuilder.append(')');
  26.                                 System.out.println(sBuilder.toString());
  27.                 }
  28.                 System.out.println("---------------begin methods list------------");
  29.                         
  30.                         Method[] methods=clazzProxy1.getMethods();
  31.                         for(Method method:methods)
  32.                         {
  33.                                 String name1=method.getName();
  34.                                 StringBuilder sBuilder1=new StringBuilder(name1);
  35.                                 sBuilder1.append('(');
  36.                                 Class[] clazzParams1=method.getParameterTypes();
  37.                                 for(Class clazzParam:clazzParams1)
  38.                                 {
  39.                                         sBuilder1.append(clazzParam.getName()).append(',');
  40.                                        
  41.                                 }
  42.                                 if(clazzParams1!=null && clazzParams1.length!=0)
  43.                                         sBuilder1.deleteCharAt(sBuilder1.length()-1);
  44.                                 sBuilder1.append(')');
  45.                                 System.out.println(sBuilder1.toString());
  46.                         
  47.                         }
  48.                 System.out.println("---------------begin create instance object------------");
  49.                 Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
  50.                 class MyInvoctionHander1 implements InvocationHandler
  51.                 {
  52.                         public Object invoke(Object proxy, Method method, Object[] args)
  53.                                         throws Throwable {
  54.                                 // TODO Auto-generated method stub
  55.                                 return null;
  56.                         }

  57.                 }
  58.                 Collection proxy1=(Collection)constructor.newInstance(new MyInvoctionHander1());
  59.                 System.out.println(proxy1);
  60.                 proxy1.clear();
  61.                 //proxy1.size();
  62.                
  63.                 Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler() {
  64.                         
  65.                         @Override
  66.                         public Object invoke(Object arg0, Method arg1, Object[] arg2)
  67.                                         throws Throwable {
  68.                                 // TODO Auto-generated method stub
  69.                                 return null;
  70.                                 }
  71.                         });
  72.                 //第三个代理对象
  73.                 Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
  74.                                 new Class[]{Collection.class},
  75.                                 new InvocationHandler() {
  76.                                        
  77.                                         @Override
  78.                                         public Object invoke(Object arg0, Method arg1, Object[] arg2)
  79.                                                         throws Throwable {
  80.                                                 ArrayList target=new ArrayList();
  81.                                                 long beginTime=System.currentTimeMillis();
  82.                                                 Object retVal=method.invoke(target,args);//这一行什么意思,不太懂
  83.                                                 long endTime=System.currentTimeMillis();
  84.                                                 System.out.println(method.getName()+"run time of"+(endTime-beginTime));
  85.                                                 return retVal;
  86.                                                 }
  87.                                         });
  88.                 proxy3.add("xxxx");
  89.                 proxy3.add("sdf");
  90.                 proxy3.add("sffgf");
  91.                 System.out.println(proxy3.size());
  92.         }               
  93. }        
  94.         
复制代码
第84,86这两行怎么老有错,还有84行什么意思呢

作者: 依旧    时间: 2013-9-22 00:54
注意看,你invoke方法参数的命名和老师视频讲解的不一样,修改一下即可!

Object retVal = arg1.invoke(target, arg2);
[size=-1]Object
invoke(Object obj, Object... args)
          对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。


作者: 第一印象    时间: 2013-9-22 08:49
一、对于你有错误的地方是参数写错了,从你写错的地方可以看出楼主对代理的了解还不是很到位,我建议再多看几次视频,强化一下理解,有些东西看一遍或两遍比较难理解,但是多看两次,就能领悟了,你的invoke方法里面写的有问题,我把正确的贴出来:
  1. public Object invoke(Object arg0, Method arg1, Object[] arg2)
  2.                                                 throws Throwable {
  3.                                         ArrayList target=new ArrayList();
  4.                                         long beginTime=System.currentTimeMillis();
  5.                                         Object retVal=arg1.invoke(target,arg2);//这一行什么意思,不太懂
  6.                                         long endTime=System.currentTimeMillis();
  7.                                         System.out.println(arg1.getName()+"run time of"+(endTime-beginTime));
  8.                                         return retVal;
  9.                                         }
  10.                                 });
复制代码
二、84行代码的意思是让代理去调用目标类的方法,我把这句话都解释下:
Object retVal=arg1.invoke(target,arg2);
Object retVal:这个是接收invoke方法返回的参数,其实就是调用目标类的方法返回的参数
arg1.invoke:这是调用目标类的方法,什么意思呢,就说,如果你想做ArrayList类的代理,那这就是调用ArrayList的一个方法
target:这是目标类对象,也就是你要代理谁
arg2:这个是你要代理的那个对象的一个方法的所有参数,比如说你要代理ArrayList,做完代理后,你想通过代理类调用ArrayList的add方法,add方法有一个参数Object a,那么arg2就是这个a参数

作者: 奔跑的二叉树    时间: 2013-9-22 09:44
第一印象 发表于 2013-9-22 08:49
一、对于你有错误的地方是参数写错了,从你写错的地方可以看出楼主对代理的了解还不是很到位,我建议再多看 ...

很详细,这真是极好的
作者: 杨增坤    时间: 2013-9-22 21:32
依旧 发表于 2013-9-22 00:54
注意看,你invoke方法参数的命名和老师视频讲解的不一样,修改一下即可!

Object retVal = arg1.invoke(ta ...

注意排版




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