黑马程序员技术交流社区

标题: 代理类实例类型转换异常 [打印本页]

作者: 潘东升    时间: 2012-6-6 18:25
标题: 代理类实例类型转换异常
本帖最后由 潘东升 于 2012-6-6 18:27 编辑

代理类创建实例返回值为Objec,使用(List)转换类型可以,而用ArrayList就会出现类型转换异常
  1. import java.lang.reflect.*;
  2. import java.util.*;
  3. public class ProxyArrayList1 {
  4. public static void main(String[]  args){

  5. //-----???这里类型转换为ArrayList会出现 $Proxy0 cannot be cast to java.util.ArrayList
  6. List proxy = (ArrayList)Proxy.newProxyInstance(List.class.getClassLoader(),
  7. new Class[]{List.class},
  8. new InvocationHandler(){
  9. @Override
  10. public Object invoke(Object proxy, Method method,
  11. Object[] args) throws Throwable {
  12. ArrayList list = new ArrayList();
  13. System.out.println("方法调用前");
  14. Object retVal = method.invoke(list, args);
  15. System.out.println("方法调用后");
  16. return retVal;
  17. }
  18. });
  19. proxy.add("原来的处理方法");
  20. System.out.println("proxy");
  21. }
  22. }
复制代码

作者: 刘蕴学    时间: 2012-6-6 21:01
首先,代理类并非ArrayList的子类,虽然他们同样都是list的子类,但他们是兄弟。。。

另外,代理的实现方式是转移调用,或者说是拦截模式,你调用的是代理类的方法,而非ArrayList的方法,这种调用的转移是通过你的invocationhandler转发的。。。

不多说了,直接给你看下代理类的源代码你就知道了,这是我自己实现的动态代理,用的是内存中的动态编译技术
  1. public class Proxy$0 implements java.util.List
  2. {
  3.         public question3.ArrayListProxy_4.ProxyHandler h;
  4.         public boolean add(java.lang.Object arg0)
  5.         {
  6.                 Object obj = null;
  7.                 try
  8.                 {
  9.                         obj = h.invoke(java.util.List.class.getMethod("add",java.lang.Object.class),arg0);
  10.                 }
  11.                 catch (Exception e)
  12.                 {
  13.                         e.printStackTrace();
  14.                 }
  15.                 return (Boolean)obj;
  16.         }
  17.         public void add(int arg0,java.lang.Object arg1)
  18.         {
  19.                 Object obj = null;
  20.                 try
  21.                 {
  22.                         obj = h.invoke(java.util.List.class.getMethod("add",int.class,java.lang.Object.class),arg0,arg1);
  23.                 }
  24.                 catch (Exception e)
  25.                 {
  26.                         e.printStackTrace();
  27.                 }
  28.                 return;
  29.         }
  30.         public java.lang.Object get(int arg0)
  31.         {
  32.                 Object obj = null;
  33.                 try
  34.                 {
  35.                         obj = h.invoke(java.util.List.class.getMethod("get",int.class),arg0);
  36.                 }
  37.                 catch (Exception e)
  38.                 {
  39.                         e.printStackTrace();
  40.                 }
  41.                 return (java.lang.Object)obj;
  42.         }
  43.         public boolean equals(java.lang.Object arg0)
  44.         {
  45.                 Object obj = null;
  46.                 try
  47.                 {
  48.                         obj = h.invoke(java.util.List.class.getMethod("equals",java.lang.Object.class),arg0);
  49.                 }
  50.                 catch (Exception e)
  51.                 {
  52.                         e.printStackTrace();
  53.                 }
  54.                 return (Boolean)obj;
  55.         }
  56.         public int hashCode()
  57.         {
  58.                 Object obj = null;
  59.                 try
  60.                 {
  61.                         obj = h.invoke(java.util.List.class.getMethod("hashCode",new Class<?>[]{}),new Object[]{});
  62.                 }
  63.                 catch (Exception e)
  64.                 {
  65.                         e.printStackTrace();
  66.                 }
  67.                 return (Integer)obj;
  68.         }
  69.         public int indexOf(java.lang.Object arg0)
  70.         {
  71.                 Object obj = null;
  72.                 try
  73.                 {
  74.                         obj = h.invoke(java.util.List.class.getMethod("indexOf",java.lang.Object.class),arg0);
  75.                 }
  76.                 catch (Exception e)
  77.                 {
  78.                         e.printStackTrace();
  79.                 }
  80.                 return (Integer)obj;
  81.         }
  82.         public void clear()
  83.         {
  84.                 Object obj = null;
  85.                 try
  86.                 {
  87.                         obj = h.invoke(java.util.List.class.getMethod("clear",new Class<?>[]{}),new Object[]{});
  88.                 }
  89.                 catch (Exception e)
  90.                 {
  91.                         e.printStackTrace();
  92.                 }
  93.                 return;
  94.         }
  95.         public boolean contains(java.lang.Object arg0)
  96.         {
  97.                 Object obj = null;
  98.                 try
  99.                 {
  100.                         obj = h.invoke(java.util.List.class.getMethod("contains",java.lang.Object.class),arg0);
  101.                 }
  102.                 catch (Exception e)
  103.                 {
  104.                         e.printStackTrace();
  105.                 }
  106.                 return (Boolean)obj;
  107.         }
  108.         public boolean isEmpty()
  109.         {
  110.                 Object obj = null;
  111.                 try
  112.                 {
  113.                         obj = h.invoke(java.util.List.class.getMethod("isEmpty",new Class<?>[]{}),new Object[]{});
  114.                 }
  115.                 catch (Exception e)
  116.                 {
  117.                         e.printStackTrace();
  118.                 }
  119.                 return (Boolean)obj;
  120.         }
  121.         public int lastIndexOf(java.lang.Object arg0)
  122.         {
  123.                 Object obj = null;
  124.                 try
  125.                 {
  126.                         obj = h.invoke(java.util.List.class.getMethod("lastIndexOf",java.lang.Object.class),arg0);
  127.                 }
  128.                 catch (Exception e)
  129.                 {
  130.                         e.printStackTrace();
  131.                 }
  132.                 return (Integer)obj;
  133.         }
  134.         public boolean addAll(int arg0,java.util.Collection arg1)
  135.         {
  136.                 Object obj = null;
  137.                 try
  138.                 {
  139.                         obj = h.invoke(java.util.List.class.getMethod("addAll",int.class,java.util.Collection.class),arg0,arg1);
  140.                 }
  141.                 catch (Exception e)
  142.                 {
  143.                         e.printStackTrace();
  144.                 }
  145.                 return (Boolean)obj;
  146.         }
  147.         public boolean addAll(java.util.Collection arg0)
  148.         {
  149.                 Object obj = null;
  150.                 try
  151.                 {
  152.                         obj = h.invoke(java.util.List.class.getMethod("addAll",java.util.Collection.class),arg0);
  153.                 }
  154.                 catch (Exception e)
  155.                 {
  156.                         e.printStackTrace();
  157.                 }
  158.                 return (Boolean)obj;
  159.         }
  160.         public java.util.Iterator iterator()
  161.         {
  162.                 Object obj = null;
  163.                 try
  164.                 {
  165.                         obj = h.invoke(java.util.List.class.getMethod("iterator",new Class<?>[]{}),new Object[]{});
  166.                 }
  167.                 catch (Exception e)
  168.                 {
  169.                         e.printStackTrace();
  170.                 }
  171.                 return (java.util.Iterator)obj;
  172.         }
  173.         public int size()
  174.         {
  175.                 Object obj = null;
  176.                 try
  177.                 {
  178.                         obj = h.invoke(java.util.List.class.getMethod("size",new Class<?>[]{}),new Object[]{});
  179.                 }
  180.                 catch (Exception e)
  181.                 {
  182.                         e.printStackTrace();
  183.                 }
  184.                 return (Integer)obj;
  185.         }
  186.         public java.lang.Object[] toArray(java.lang.Object[] arg0)
  187.         {
  188.                 Object obj = null;
  189.                 try
  190.                 {
  191.                         obj = h.invoke(java.util.List.class.getMethod("toArray",java.lang.Object[].class),arg0);
  192.                 }
  193.                 catch (Exception e)
  194.                 {
  195.                         e.printStackTrace();
  196.                 }
  197.                 return (java.lang.Object[])obj;
  198.         }
  199.         public java.lang.Object[] toArray()
  200.         {
  201.                 Object obj = null;
  202.                 try
  203.                 {
  204.                         obj = h.invoke(java.util.List.class.getMethod("toArray",new Class<?>[]{}),new Object[]{});
  205.                 }
  206.                 catch (Exception e)
  207.                 {
  208.                         e.printStackTrace();
  209.                 }
  210.                 return (java.lang.Object[])obj;
  211.         }
  212.         public boolean remove(java.lang.Object arg0)
  213.         {
  214.                 Object obj = null;
  215.                 try
  216.                 {
  217.                         obj = h.invoke(java.util.List.class.getMethod("remove",java.lang.Object.class),arg0);
  218.                 }
  219.                 catch (Exception e)
  220.                 {
  221.                         e.printStackTrace();
  222.                 }
  223.                 return (Boolean)obj;
  224.         }
  225.         public java.lang.Object remove(int arg0)
  226.         {
  227.                 Object obj = null;
  228.                 try
  229.                 {
  230.                         obj = h.invoke(java.util.List.class.getMethod("remove",int.class),arg0);
  231.                 }
  232.                 catch (Exception e)
  233.                 {
  234.                         e.printStackTrace();
  235.                 }
  236.                 return (java.lang.Object)obj;
  237.         }
  238.         public java.lang.Object set(int arg0,java.lang.Object arg1)
  239.         {
  240.                 Object obj = null;
  241.                 try
  242.                 {
  243.                         obj = h.invoke(java.util.List.class.getMethod("set",int.class,java.lang.Object.class),arg0,arg1);
  244.                 }
  245.                 catch (Exception e)
  246.                 {
  247.                         e.printStackTrace();
  248.                 }
  249.                 return (java.lang.Object)obj;
  250.         }
  251.         public java.util.ListIterator listIterator(int arg0)
  252.         {
  253.                 Object obj = null;
  254.                 try
  255.                 {
  256.                         obj = h.invoke(java.util.List.class.getMethod("listIterator",int.class),arg0);
  257.                 }
  258.                 catch (Exception e)
  259.                 {
  260.                         e.printStackTrace();
  261.                 }
  262.                 return (java.util.ListIterator)obj;
  263.         }
  264.         public java.util.ListIterator listIterator()
  265.         {
  266.                 Object obj = null;
  267.                 try
  268.                 {
  269.                         obj = h.invoke(java.util.List.class.getMethod("listIterator",new Class<?>[]{}),new Object[]{});
  270.                 }
  271.                 catch (Exception e)
  272.                 {
  273.                         e.printStackTrace();
  274.                 }
  275.                 return (java.util.ListIterator)obj;
  276.         }
  277.         public java.util.List subList(int arg0,int arg1)
  278.         {
  279.                 Object obj = null;
  280.                 try
  281.                 {
  282.                         obj = h.invoke(java.util.List.class.getMethod("subList",int.class,int.class),arg0,arg1);
  283.                 }
  284.                 catch (Exception e)
  285.                 {
  286.                         e.printStackTrace();
  287.                 }
  288.                 return (java.util.List)obj;
  289.         }
  290.         public boolean containsAll(java.util.Collection arg0)
  291.         {
  292.                 Object obj = null;
  293.                 try
  294.                 {
  295.                         obj = h.invoke(java.util.List.class.getMethod("containsAll",java.util.Collection.class),arg0);
  296.                 }
  297.                 catch (Exception e)
  298.                 {
  299.                         e.printStackTrace();
  300.                 }
  301.                 return (Boolean)obj;
  302.         }
  303.         public boolean removeAll(java.util.Collection arg0)
  304.         {
  305.                 Object obj = null;
  306.                 try
  307.                 {
  308.                         obj = h.invoke(java.util.List.class.getMethod("removeAll",java.util.Collection.class),arg0);
  309.                 }
  310.                 catch (Exception e)
  311.                 {
  312.                         e.printStackTrace();
  313.                 }
  314.                 return (Boolean)obj;
  315.         }
  316.         public boolean retainAll(java.util.Collection arg0)
  317.         {
  318.                 Object obj = null;
  319.                 try
  320.                 {
  321.                         obj = h.invoke(java.util.List.class.getMethod("retainAll",java.util.Collection.class),arg0);
  322.                 }
  323.                 catch (Exception e)
  324.                 {
  325.                         e.printStackTrace();
  326.                 }
  327.                 return (Boolean)obj;
  328.         }
  329. }
复制代码

作者: 刘蕴学    时间: 2012-6-6 21:35
本帖最后由 刘蕴学 于 2012-6-6 21:36 编辑
ttkl123654 发表于 2012-6-6 21:22
能具体说说你这个代理和版主那个代理的区别吗?
实现上有差异?还是说你这个实现的功能比较全?
proxy.ne ...

我这个和sun的实现方式是一样的,只不过sun的那个底层是groove,我这个是全用的java api,而我这个可以diy,至于你所说的只支持一个接口,你肯定没仔细看参数列表最后一个是可变参数,另外,本地方法(非接口方法,被代理类的自有方法)的代理,以这两种方式都拿不到,代理只负责接口方法的转发,如果想实现要做一点改变

最后说一点,2楼的代码是程序自动生成的
作者: 潘东升    时间: 2012-6-6 21:36
刘蕴学 发表于 2012-6-6 21:01
首先,代理类并非ArrayList的子类,虽然他们同样都是list的子类,但他们是兄弟。。。

另外,代理的实现方 ...

这个,我查资料的时候也想过,每个方法都覆盖,很麻烦,看来要实现一个类的代理和实现一个接口的代理果然两回事
作者: 刘蕴学    时间: 2012-6-6 21:37
本帖最后由 刘蕴学 于 2012-6-6 21:40 编辑
潘东升 发表于 2012-6-6 21:36
这个,我查资料的时候也想过,每个方法都覆盖,很麻烦,看来要实现一个类的代理和实现一个接口的代理果然 ...

难倒是不难,本地方法一样可以被代理,但是这样的话,上层接口的迭代会更复杂,这个代理api 是可以自己实现的,完整的实现,用的技术多一些而已。就算是sun的代理api,实现方面也是一样的动态源代码编译在加载,同样的套路。
作者: 潘东升    时间: 2012-6-6 21:50
刘蕴学 发表于 2012-6-6 21:37
难倒是不难,本地方法一样可以被代理,但是这样的话,上层接口的迭代会更复杂,这个代理api 是可以自己实 ...

还是不太懂,这个我搞了两天两夜都想不明白,视频都翻了好几遍,思路有些乱,谢谢了先
作者: 闾丘日月    时间: 2012-6-6 23:22
代理确实麻烦。。感觉很模模糊糊的




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