黑马程序员技术交流社区

标题: 代理问题!求大神指点 [打印本页]

作者: 徐青松    时间: 2014-2-22 22:53
标题: 代理问题!求大神指点
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这样的实现类了。求解
作者: e.c    时间: 2014-2-23 00:02
问题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创建代理类对象时,你必须让它知道它要创建的代理类对象具有哪些方法。这就是接口这个参数的作用。

                                
作者: 徐青松    时间: 2014-2-23 10:03
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,请指点
作者: 我要的幸福呢    时间: 2014-2-23 10:15
问题1的问题在于newProxyInstance方法的第二个参数接收的是一个Class类型的数组,如果直接传List.class肯定不行,改为new Class[]{List.class}试一下
作者: e.c    时间: 2014-2-23 11:28
徐青松 发表于 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}
作者: 徐青松    时间: 2014-2-23 20:03
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
ArrayList继承自List,List实现了Collection接口。那么ArrayList.class.getInterfaces结果就是Collection.你不能将一个Collecttion转成List,更加不可能转成ArrayList




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