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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 夏晓彤 中级黑马   /  2013-3-3 17:12  /  1271 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 夏晓彤 于 2013-3-9 14:37 编辑

下面是张老师动态代理里面的代码,我的理解和问题都在后面注释了,请各位帮帮忙看下
public class ProxyTest {
        public static void main(String[] args) {
                Collection proxy1 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
                                new Class[]{Collection.class} ,
                                new InvocationHandler(){
                        ArrayList trage = new ArrayList();
                        //执行proxy1.add("xxt1");这里的Object proxy就是proxy1,method是add,args是“xxt1”
                                        public Object invoke(Object proxy, Method method,
                                                        Object[] args) throws Throwable {
                                                // TODO Auto-generated method stub
                                                long beginTime = System.currentTimeMillis();
                                                Object recval=method.invoke(trage, args);      //目标类对象调用add("xxt1")方法
                                                long endTime = System.currentTimeMillis();
                                                System.out.println(method.getName() + " running time of " + (endTime-beginTime));
                                                System.out.println(recval);           //这里为什么打赢的是true???
                                                return recval;
                                        }
                                        }
                );
                proxy1.add("xxt1");
                proxy1.add("xxt2");
                proxy1.add("xxt3");
                System.out.println(proxy1);     //这一句为什么输出的是toString running time of 0  [xxt1, xxt2, xxt3]???

                System.out.println(proxy1.size());       //也是先输出size running time of 0???
                Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
                System.out.println(clazz.getName());
               
        }
               
}

4 个回复

倒序浏览
第一个问题,为什么打印的true,是因为代理类调用了add方法,而该方法返回的是一个boolean类型的值,添加成功就返回true

第二个问题,为什么先输出size running time of 0,当代理类对象每调用一次Collection的方法,就会调用InvocationHandler对象中的invoke方法,
            所有每次都要执行该方法中的代码,就会先打印size running time of 0,再打印System.out.println(recval);   
第三个问题,打印结果 [xxt1, xxt2, xxt3]???, 代理类对象调用的实际上是Collection的toString方法,并打印的是目标对象中的数据,所以打印的就是
            ArrayList中的内容。





回复 使用道具 举报
这里为什么打赢的是true???
答:目标ArrayList的add()方法返回的布尔型,添加成功就会返回true!
这一句为什么输出的是toString running time of 0  [xxt1, xxt2, xxt3]???
答:首先,System.out.println()方法会自动调用要打印的引用类型变量的toString()方法,因为proxy1是个动态代理对象,
    在调用其这个toString()方法的时候就会调用关联的InvocationHandle的invoke()方法,
    method.invoke(trage, args)这句将执行(ArrayList)target的toString()方法,返回值为“ [xxt1, xxt2, xxt3]”字符串,
   (注:ArrayList重写Object的toString()方法返回的为 “[元素1,元素与2,元素3........]”字符串形式)并赋给recval,
    method.getName() 的值为toString,
     所以,System.out.println(method.getName() + " running time of " + (endTime-beginTime));+ System.out.println(recval);  就是你获得打印值。
也是先输出size running time of 0
答:同上!         
   
回复 使用道具 举报
第一://这里为什么打赢的是true???
不是打印的方法的名称.而是返回值.
因为add方法的返回值就是true.

第二: //这一句为什么输出的是toString running time of 0  [xxt1, xxt2, xxt3]???
toString 是方法名.  因为打印集合要调用toString方法
[xxt1, xxt2, xxt3]: 是重写toString后的输出结构.

第三:  //也是先输出size running time of 0???
第一个3是recval返回值
第二个3是size()的返回值
第三先打印名称是因为 在return之间执行的.  没有return的值就没有集合对象.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马