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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黄云南 于 2012-3-29 02:50 编辑
  1.    class Test2 {
  2.               public static void main(String[] args) {
  3.                 Collection proxyArrayList = (Collection)Proxy.newProxyInstance(

  4.                                 Collection.class.getClassLoader(),

  5.                                 new Class[]{Collection.class},
  6.                                                
  7.                                 new InvocationHandler() {
  8.                                         ArrayList target = new ArrayList();
  9.                                                         public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  10.                                         System.out.println(method);
  11.                                                        System.out.println(target.getClass().getMethod("add", Object.class));
  12.                                                         Object obj = method.invoke(target, args);
  13.                                                        return obj;  
  14.                                                 }
  15.                                         });
  16.                         proxyArrayList.add("abc");

  17.                 }
复制代码
打印结果:
public abstract boolean java.util.Collection.add(java.lang.Object)
public boolean java.util.ArrayList.add(java.lang.Object)


上面是张孝祥老师讲解动态代理类时的一段代码,我很奇怪传进invoke的那个method是谁的方法,于是改了下代码验证,
method的字节码对象和target的add方法的字节码文件不一样啊,也就是method的add方法不是target的add方法。
method的add方法是public abstract boolean java.util.Collection.add中的方法他的方法是空的啊怎么能调用invoke方法,
更奇怪的是一个空的方法怎么向集合中添加元素呢。

3 个回复

倒序浏览

import java.lang.reflect.*;

public class TestAgent {
    public static void main(String[] args) {
            Agent agent=new Agent();
            BAgentFace bAgentFace=null;
            agent.setObj(new BAgent());
            bAgentFace=(BAgentFace)Proxy.newProxyInstance(BAgentFace.class.getClassLoader(),new Class[]{BAgentFace.class},agent);
            bAgentFace.add();
    }
}
class Agent implements InvocationHandler
{
        private Object obj;
       
        public void setObj(Object obj) {
                this.obj = obj;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
               
                return method.invoke(obj,args);
        }
       
}
class BAgent implements BAgentFace
{
        public void add()
        {
                System.out.println("ni hao");
        }
}
interface BAgentFace
{
        public void add();
}

点评

原来是这样!!!多谢啦!!!!  发表于 2012-3-29 13:57
回复 使用道具 举报
本帖最后由 王国华 于 2012-3-29 11:42 编辑

这里利用了java中一个重要的特征,多态,简单点说,父类引用指向了子类对象,其实就是
Collectioin target =new ArrayList();
tartget.add();
多态的出现是为了增强程序的扩展性,如果你把target换成别的集合还可以使用这个程序,如果你写成ArrayList它就是一个死程序,没有扩展性。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马