黑马程序员技术交流社区

标题: method.invoke(target,args)是否父类的引用调用了子类对象特有方法 [打印本页]

作者: 黎志文    时间: 2013-7-22 05:31
标题: method.invoke(target,args)是否父类的引用调用了子类对象特有方法
本帖最后由 杨兴庭 于 2013-7-22 21:25 编辑
  1. public static Object getProxyInstance(final Object target,final Advice adv) //这里目标类的对象被提升至Object
  2. {
  3.       Object proxy =  Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces()
  4.      ,new InvocationHandler()  //匿名内部类
  5.      {
  6.           @Override
  7.           public Object invoke(Object proxy,Method method,Object[] args) throws Throwable
  8.           {
  9.               adv.beforeMethod(method);
  10.              Object retVal = method.invoke(target,args);
  11. /* 这里目标类的对象要调用目标类中的方法,比如目标类是ArrayList,这里ArrayList的对象list调用add方法,但是list在传进来的时候已经被提升至Object,
  12. 而add方法又不是Object类中的方法,也就是说父类的引用调用了子类中特有的方法,这样不会出错么?*/
  13.              adv.afterMethod(method);
  14.              return retVal;
  15.           }
  16.      });
  17. }
复制代码
无意间想到了一个问题,比较纠结:我们在定义一个方法getProxyInstance(Object target, Advice adv),用于获取任意一个目标类的代理类时,要给此方法传递两个参数,
其一是目标类对象,其二是扩展类代码的对象,这里扩展类代码的类型是Advice,是因为此方法内部会用到Advice中特有的两个方法beforeMethod和afterMethod,但是目
标类对象(ArrayList list)在传给此方法的第一个参数时,已经被提升至Object类型,那么 method.invoke( target,args) 这里的method是add方法时,即add.invoke(target,args) ,
这个时候父类的引用调用了子类list中特有的方法add,难道不会出错么?代码如上。


作者: 草貌路飞    时间: 2013-7-22 10:35
我也刚看完代理..我觉得这里应该理解成是对象调用了这个方法,只要这个对象中有这个方法就行了。虽然一个对象的引用可能是Object类型,但通过反射不是可以得到这个对象的真实类型,并可以获取它的所有元素么。所以当Method对象invoke时,只要这个target对象中包含这个方法就行了吧.
作者: liuzhming    时间: 2013-7-22 10:39
在以前编写的继承关系代码中,父类的引用是不能调用子类中特有的方法的,在编译时就会出错,但反射却允许。反射允许我们调用任意一个对象的任意一个方法。java程序可以获悉一个类的完整构造,生成它的对象实体,对它的属性设值,调用它的方法,相当于把类和对象看透了。在这里target只是引用,目标类对象是要反射的对象。反射能够调用它的所有方法。由此我们看到在编译时无法做到的事情,在反射时能够做到,反射提供了强大的功能。





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