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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

写了一个ArrayList的动态代理proxy  可是这个对象只能调用Collection中的方法 ArrayList中的有些方法却不能调用 应该怎么解决呢? 问题已经在代码中标明
package cn.taotao.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                final ArrayList target = new ArrayList();
                Collection proxy = (Collection) getProxy(target);//proxy是ArrayList的代理
               
                //测试代理
                //((ArrayList)proxy).ensureCapacity(20);//这里会报错,为什么?注释掉这一行就可以运行正常
                                //proxy.ensureCapacity(20);//这样也报错,为什么?要怎么样才能调用ArrayList所有的方法
                proxy.add(1);
                proxy.add(2);
                proxy.add(3);
                System.out.println(proxy.size());
                System.out.println(proxy.getClass().getName());

        }

        public static Object getProxy(final Object target) {
                Object proxy = Proxy.newProxyInstance(
                                target.getClass().getClassLoader(),
                                target.getClass().getInterfaces(),
                                new InvocationHandler() {
                                       
                                        @Override
                                        public Object invoke(Object proxy, Method method, Object[] args)
                                                        throws Throwable {
                                                long beginTime = System.currentTimeMillis();//附加功能
                                                Object reValue = method.invoke(target, args);//调用目标的方法
                                                long endTime = System.currentTimeMillis();//附加功能
                                                //计算方法运行的时间
                                                System.out.println(method.getName() + "'s ran time is " + (endTime-beginTime));
                                                return reValue;
                                        }
                                });
                return proxy;
        }
       
}

3 个回复

倒序浏览
Proxy.newProxyInstance方法会做如下几件事:

1,根据传入的第二个参数interfaces动态生成一个类,实现interfaces中的接口,该例中即BusinessProcessor接口的processBusiness方法。并且继承了Proxy类,重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了$Proxy0类

2,通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load

3,利用第三个参数,调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化对象的几个Method成员变量

4,将$Proxy0的实例返回给客户端。

简言之,用jdk的动态代理生成的代理类,代理类实际上是实现了目标类的接口,因此,不能给具体的实现类产生代理类,只能给接口产生代理。

如果想给ArrayList生成代理,可以使用CGLIB或者是javassist都可以,但是,jdk的proxy是不可以的。
希望能帮到你
回复 使用道具 举报
Proxy.newProxyInstance方法会做如下几件事:

1,根据传入的第二个参数interfaces动态生成一个类,实现interfaces中的接口,该例中即BusinessProcessor接口的processBusiness方法。并且继承了Proxy类,重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了$Proxy0类

2,通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load

3,利用第三个参数,调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化对象的几个Method成员变量

4,将$Proxy0的实例返回给客户端。

简言之,用jdk的动态代理生成的代理类,代理类实际上是实现了目标类的接口,因此,不能给具体的实现类产生代理类,只能给接口产生代理。

如果想给ArrayList生成代理,可以使用CGLIB或者是javassist都可以,但是,jdk的proxy是不可以的
回复 使用道具 举报
代理对象,只是宣称了,他实现的真实对象的接口,ArrayList 他实现了List,Collection接口,你可以这样写
Collection con = (Collection) getProxy(target);   List l =  (List) getProxy(target);你想用ArrayList功能就把他转成List对象,用l 就行了,
永远不可能 (ArrayList) getProxy(target); 因为代理只是看成是一个接口的对象

评分

参与人数 1技术分 +2 收起 理由
宁超 + 2

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马