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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周恺 中级黑马   /  2012-7-18 08:11  /  1432 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周恺 于 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, 下载次数: 103)

错误提示

错误提示

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

error.jpg

1 个回复

倒序浏览
java自带的Proxy是无法实现的
看看这一句:
Class proArrayList=Proxy.getProxyClass(ArrayList.class.getClassLoader(),ArrayList.class.getInterfaces());   
你传给getProxyClass的第二个参数是一个接口的数组
所以代理类只是实现了这些接口,比如Collection接口,List接口
所以你可以使用这些接口里的方法

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

视频中有提到第三方库类CGLIB
不根据接口而是根据类本身来代理
应该就可以实现你的这个想法:
代理一个类的所有方法,包括特有方法
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马