A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱玉玺 中级黑马   /  2013-1-30 00:38  /  1957 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 朱玉玺 于 2013-1-30 00:50 编辑
  1. import java.lang.reflect.Constructor;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Proxy;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.List;

  9. interface Advice {
  10.         void beforeMethod(Method method);
  11.         void afterMethod(Method method);
  12. }
  13. class MyAdvice implements Advice {
  14.         long startTime=0;
  15.         @Override
  16.         public void beforeMethod(Method method) {               
  17.                  System.out.println("方法开始啦");
  18.                  startTime = System.currentTimeMillis();
  19.         }

  20.         @Override
  21.         public void afterMethod(Method method) {               
  22.                 System.out.println("方法结束啦");
  23.                 long endTime = System.currentTimeMillis();
  24.                 System.out.println(method.getName()+"  running time:"+(endTime - startTime));
  25.         }
  26. }

  27. public class ProxyTest {        
  28.         public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

  29.                 final ArrayList target = new ArrayList();
  30.                 Collection proxy =(Collection) getProxy(target,new MyAdvice());
  31. //                ArrayList it =(ArrayList) getProxy(target,new MyAdvice());        这句报错
  32.                 List proxy1 =(List) getProxy(new ArrayList(),new MyAdvice());
  33.                 Iterable it = (Iterable)getProxy(new ArrayList(),new MyAdvice());
  34.                 /*
  35.                  我的问题:1.这里的getProxy()方法传递的参数是final类型的,但为什么我传入new  ArrayList()没有定义成final,没有定义成final也通过编译而且运行正常?
  36.                        2.这里的代理设计模式,跟装饰设计模式很类似,都是传入一个类,然后返回一个新类,同时多了一些功能,这两个设计模式有什么区别?
  37.                        3.Collection 能指向这个代理类,说明这个代理类是Collection的一个实现类,但也没有标记implement怎么就实现了?
  38.                          将其强转为ArrayList编译失败,说明它是不是ArrayList或者其子类,它跟ArrayList的最大公约数是什么?
  39.                  */

  40. //                System.out.println("iterable:"+it.iterator());
  41.                 proxy1.add("lisi");
  42.                 proxy.add("wangwu");
  43.                 System.out.println(proxy.size());
  44.                
  45.         }

  46.         public static Object getProxy(final Object target,final Advice advice) {
  47.                 Object proxy3 =Proxy.newProxyInstance(
  48.                                 target.getClass().getClassLoader(),
  49.                                 target.getClass().getInterfaces(),
  50.                                 new InvocationHandler() {                                
  51.                                 @Override
  52.                                 public Object invoke(Object proxy, Method method, Object[] args)
  53.                                                 throws Throwable {
  54.                                         advice.beforeMethod(method);
  55.                                         Object retVal = method.invoke(target, args);
  56.                                         advice.afterMethod(method);
  57.                                         return retVal;
  58.                                 }
  59.                 });
  60.                 return proxy3;
  61.         }               
  62. }
复制代码

评分

参与人数 1技术分 +1 黑马币 +12 收起 理由
Rancho_Gump + 1 + 12

查看全部评分

2 个回复

倒序浏览
内部类调用外部类变量才需要final
回复 使用道具 举报
问题1、你传进去的是具体的对象,不需要类型修饰控制,所以不需要final Object object的啥东西了。
问题2、装饰设计模式与代理模式,看起来的确很相似,都有实现一个接口,都有添加功能的作用。但装饰设计模式主要关注于添加某些方法。代理模式,主要用于控制,你完全可以更改从目标(target)到客户端(client)的数据,这就是代理。
问题3、static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
          返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
这里是一个接口数组!返回:一个指定接口的代理类实例。(我只能这么理解。。。。)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马