黑马程序员技术交流社区

标题: 这个固定的代理中为什么会出现转换异常呢? [打印本页]

作者: freehiker    时间: 2013-11-26 11:09
标题: 这个固定的代理中为什么会出现转换异常呢?
本帖最后由 freehiker 于 2013-11-26 14:29 编辑
  1. package test.java;

  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. import java.util.ArrayList;
  6. import java.util.Collection;

  7. /**
  8. *
  9. *
  10. * @author rudy
  11. *
  12. */
  13. public class ArryListProxy {

  14.         /**
  15.          * @param args
  16.          */
  17.         public static void main(String[] args) {
  18.                 // TODO Auto-generated method stub
  19.                
  20.                 Collection proxy = (Collection) Proxy.newProxyInstance(
  21.                                 Collection.class.getClassLoader(),
  22.                                 Collection.class.getInterfaces(), new InvocationHandler() {
  23.                                         ArrayList target = new ArrayList();

  24.                                         @Override
  25.                                         public Object invoke(Object proxy, Method method,
  26.                                                         Object[] args) throws Throwable {
  27.                                                 long beginTime = System.currentTimeMillis();
  28.                                                 Object retVal = method.invoke(target, args);
  29.                                                 long endTime = System.currentTimeMillis();
  30.                                                 System.out.println("该方法运行了"+(endTime - beginTime)+"毫秒");
  31.                                                 return retVal;
  32.                                         }

  33.                                 });
  34.                 proxy.add("a");
  35.         }

  36. }
复制代码
运行的时候会出现转换异常的错误,$Proxy0不能转换为Collection类,求解?

作者: RuntimeError!    时间: 2013-11-26 13:24
Collection proxy = (Collection) Proxy.newProxyInstance(
                                Collection.class.getClassLoader(),
                                Collection.class.getInterfaces(),
这个地方出错了 Collection.class.getInterfaces(), 应该改成 new Class[]{Collection.class}
原因是 这个地方参数是接口,由于不是最有一个参数,所以不可以用可变参数,要用数组
作者: RuntimeError!    时间: 2013-11-26 13:25
Collection proxy = (Collection) Proxy.newProxyInstance(
                                Collection.class.getClassLoader(),
                                Collection.class.getInterfaces(),
这个地方出错了 Collection.class.getInterfaces(), 应该改成 new Class[]{Collection.class}
原因是 这个地方参数是接口,由于不是最有一个参数,所以不可以用可变参数,要用数组
作者: freehiker    时间: 2013-11-26 13:43
RuntimeError! 发表于 2013-11-26 13:25
Collection proxy = (Collection) Proxy.newProxyInstance(
                                Collection.c ...

这么改是能把问题解决了,但是Collection.class.getInterfaces()这个返回的就是一个Class[]数组噢 。而且张老师的一个方法中也有这样的应用噢
  1. private static Object getProxy(final Object target, final Advice advice) {
  2.                 Object proxy = Proxy.newProxyInstance(target.getClass()
  3.                                 .getClassLoader(), target.getClass().getInterfaces(),
  4.                                 new InvocationHandler() {
  5.                                         @Override
  6.                                         public Object invoke(Object proxy, Method method,
  7.                                                         Object[] args) throws Throwable {
  8.                                                 // TODO Auto-generated method stub
  9.                                                 advice.beginMethod();
  10.                                                 Object retVal = method.invoke(target, args);
  11.                                                 advice.endMethod();
  12.                                                 return retVal;
  13.                                         }

  14.                                 });
  15.                 return proxy;
  16.         }
复制代码

作者: freehiker    时间: 2013-11-26 13:57
  1. public class ArryListProxy {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 final ArrayList target = new ArrayList();
  8.                 Collection proxy = (Collection) getProxy(target);
  9.                 proxy.add("a");
  10.                 proxy.add("a");
  11.                 proxy.add("a");
  12.                 System.out.println(proxy);
  13.         }

  14.         private static Object getProxy(final Object target) {
  15.                 Object proxy = Proxy.newProxyInstance(
  16.                                 target.getClass().getClassLoader(),
  17.                                 target.getClass().getInterfaces(),
  18.                                 new InvocationHandler() {
  19.                                        
  20.                                         @Override
  21.                                         public Object invoke(Object proxy, Method method,
  22.                                                         Object[] args) throws Throwable {
  23.                                                 long beginTime = System.currentTimeMillis();
  24.                                                 Object retVal = method.invoke(target, args);
  25.                                                 long endTime = System.currentTimeMillis();
  26.                                                 System.out.println("该方法运行了"+(endTime - beginTime)+"毫秒");
  27.                                                 return retVal;
  28.                                         }

  29.                                 });
  30.                 return proxy;
  31.         }

  32. }
复制代码

这样把方法提取出来的话问题也就不存在了
作者: freehiker    时间: 2013-11-26 14:15
本帖最后由 freehiker 于 2013-11-26 14:17 编辑
RuntimeError! 发表于 2013-11-26 13:25
Collection proxy = (Collection) Proxy.newProxyInstance(
                                Collection.c ...

终于把原因找出来了,非常感谢您的解答。
但是Colelction.class.getInterfaces()返回的也是Class[],这是没问题的。
问题出在这个参数是代理需要实现的目标类的接口,而目标类是ArrayList,所以应该写成
ArrayList.class.getInterfaces(),这样问题就解决了。
我通过for循环,把ArrayList.class.getInterfaces()的元素和new Class[]{Collection.class}的元素打印了一下前面的是ArrayList所实现的接口
后者是Collection接口,这里因为多态的特性,所以没有问题

作者: RuntimeError!    时间: 2013-11-26 14:24
freehiker 发表于 2013-11-26 14:15
终于把原因找出来了,非常感谢您的解答。
但是Colelction.class.getInterfaces()返回的也是Class[],这是 ...

0 0 好吧0 0 我以为是new的问题呢0 0。。刚才洗澡去了 没来得及回复不好意思哈0 0。。
原来是这样哇0 0。。
作者: freehiker    时间: 2013-11-26 14:29
RuntimeError! 发表于 2013-11-26 14:24
0 0 好吧0 0 我以为是new的问题呢0 0。。刚才洗澡去了 没来得及回复不好意思哈0 0。。
原来是这样哇0 0。 ...

没事,呵呵,老师确实有提到过你说的那知识点




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