黑马程序员技术交流社区

标题: 类的代理问题 [打印本页]

作者: 周恺    时间: 2012-7-18 08:11
标题: 类的代理问题
本帖最后由 周恺 于 2012-7-19 22:43 编辑


这个问题烦了我一晚上,请高手帮忙看看.
//目的:实现ArrayList的代理类
public static void main(String[] args)
{
            
           Class proArrayList=Proxy.getProxyClass(ArrayList.class.getClassLoader()
               ,ArrayList.class.getInterfaces());                                                             //创建一个ArrayList类的代理proArrayList

            Constructor con4=proArrayList.getConstructor(InvocationHandler.class);//获取代理类的构造方法con4

            Collection al= (Collection)con4.newInstance(new InvocationHandler(){     //利用构造方法生成proArrayList的对象.InvocationHandler对象是以匿名对象方式传入
             ArrayList target=new ArrayList();
             public Object invoke(Object proxy, Method method, Object[] args)throws Throwable
                 {
                        Object obj=method.invoke(target, args);
                        return obj;
                }
                 });
             //al.trimToSize() 这样调用编译器无法通过.
              
}
我的问题是,当我构造代理类对象al的时候,却只能以Collection接口类型进行接收.也就是说,由con4 newInstance出来的对象原本是Object类型的,必须转换成Collection
但是如果这样的话,那么一些ArrayList的特有方法不是无法实现代理了吗?如trimToSize()并不是由实现任何接口获取的,是ArrayList扩展的方法.就无法代理.

如果我使用ArrayList类型来接收代理对象,如:
  ArrayList al= (ArrayList )con4.newInstance(new InvocationHandler(){     //利用构造方法生成proArrayList的对象.InvocationHandler对象是以匿名对象方式传入
             ArrayList target=new ArrayList();
             public Object invoke(Object proxy, Method method, Object[] args)throws Throwable
                 {
                        Object obj=method.invoke(target, args);
                        return obj;
                }
                 });
编译器会告知类型转换错误:
Exception in thread "main" java.lang.ClassCastException: $Proxy1 cannot be cast to java.util.ArrayList
at d15Klo.com.cn.PoxyTest.main(PoxyTest.java:74)
我想请问一下,如果我需要实现代理一个类的所有方法,包括特有方法该怎么做?

error.jpg (30.37 KB, 下载次数: 100)

错误提示

错误提示

error.jpg (30.37 KB, 下载次数: 95)

error.jpg

作者: 温少邦    时间: 2012-7-18 11:37
java自带的Proxy是无法实现的
看看这一句:
Class proArrayList=Proxy.getProxyClass(ArrayList.class.getClassLoader(),ArrayList.class.getInterfaces());   
你传给getProxyClass的第二个参数是一个接口的数组
所以代理类只是实现了这些接口,比如Collection接口,List接口
所以你可以使用这些接口里的方法

而ArrayList自身的trimToSize()方法就没有实现了
因为你传递给它的接口里面没有这个方法
所以它也就没有去代理这个方法

视频中有提到第三方库类CGLIB
不根据接口而是根据类本身来代理
应该就可以实现你的这个想法:
代理一个类的所有方法,包括特有方法




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