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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 徐青松 中级黑马   /  2014-2-22 22:53  /  1212 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

List cons2 = (List) Proxy.newProxyInstance(
                                List.class.getClassLoader(),
                                List.class.getInterfaces(),//问题1:有人说getInterfaces()方法获得的是该接口的父接口即Collection接口,是这样的吗?在张老师的演示中接口代理类直接是接口的class即List.class为什么编译都通不过?!
                                new InvocationHandler() {
                                        ArrayList al = new ArrayList();

                                        @Override
                                        public Object invoke(Object proxy, Method method,
                                                        Object[] args) throws Throwable {
                                                // TODO Auto-generated method stub
                                                long startTime = System.currentTimeMillis();
                                                Object retVal = method.invoke(al, args);
                                                long endTime = System.currentTimeMillis();
                                                System.out.println(method.getName() + " run time is "
                                                                + (endTime - startTime));
                                                return retVal;
                                        }
                                });
                cons2.add("bxd");
                cons2.add("qsl");
                cons2.add("ly");
                System.out.println(cons2.size());
//问题2,上面的代码就算问题一处编译通过了,为什么代理类对象必须是参数类加载器的父类接口才是正确的,张老师演示的全是Collection接口为什么就没问题,换成全List接口就会有问题,更别说ArrayList这样的实现类了。求解

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

6 个回复

倒序浏览
问题1:翻译是没问题的。运行时会报错。类转换异常。
首先List.class.getInterfaces()得到的是List这个接口所实现的类即Collection
Proxy.newProxyInstance创建代理类对象的时候传进了List.class.getInterfaces(),说明这个生成的代理类对象实现了Collection接口。
List cons2 = (List) Proxy.newProxyInstance而你又试图把生成的代理类对象Collection强制转换成List类型。
所以报错。改成Collection = (Collection) Proxy.newProxyInstance就没问题了。
Collection con = (Collection) Proxy.newProxyInstance(List.class.getClassLoader(),new Class[]{ List.class},new InvicationHandler(){.....});这样也是没问题的。可以向上转型

问题2并不是说必须是参数类加载器的父类接口。而是说:Proxy创建代理类对象时,你必须让它知道它要创建的代理类对象具有哪些方法。这就是接口这个参数的作用。

                                

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
e.c 发表于 2014-2-23 00:02
问题1:翻译是没问题的。运行时会报错。类转换异常。
首先List.class.getInterfaces()得到的是List这个接口 ...

那我就想创建List的代理类,接口参数处传List.class连编译都通不过,必须写List.class.getInterfaces()才能编译,这是怎么回事。最后,要是我想创建List的代理类,将张老师中代码处的Collection全改成List不就是创建的List代理类吗?如果不是,那该怎样实现。为啥视频的示例全是Collection就是Collection的代理类,而List代理类就不能全是List,请指点
回复 使用道具 举报
问题1的问题在于newProxyInstance方法的第二个参数接收的是一个Class类型的数组,如果直接传List.class肯定不行,改为new Class[]{List.class}试一下
回复 使用道具 举报
徐青松 发表于 2014-2-23 10:03
那我就想创建List的代理类,接口参数处传List.class连编译都通不过,必须写List.class.getInterfaces()才 ...

楼上我写过了哦:
Collection con = (Collection) Proxy.newProxyInstance(List.class.getClassLoader(),new Class[]{ List.class},new InvicationHandler(){.....});这样也是没问题的。可以向上转型
传List.class接口的话要打包成数组,你看下上面参数里的new Class[]{List.class}
回复 使用道具 举报 1 0
e.c 发表于 2014-2-23 11:28
楼上我写过了哦:
Collection con = (Collection) Proxy.newProxyInstance(List.class.getClassLoader(), ...

嗯啊,向上转型我能懂,还有个问题想请教,若我想生成ArrayList的代理:ArrayList cons2 = (ArrayList) Proxy.newProxyInstance(
                                ArrayList.class.getClassLoader(),
                                ArrayList.class.getInterfaces(),
                                new InvocationHandler() {·····}
为什么ArrayList cons2 = (ArrayList) Proxy.newProxyInstance  这里用ArrayList不行,必须用List等才行,为什么,代理有什么限制吗?
回复 使用道具 举报
e.c 中级黑马 2014-2-23 20:31:34
7#
ArrayList继承自List,List实现了Collection接口。那么ArrayList.class.getInterfaces结果就是Collection.你不能将一个Collecttion转成List,更加不可能转成ArrayList
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马