1、“通过代理创建了一个target ArrayList的实例对象”
2、“那现在我的问题是能不能通过代理返回是这个ArrayList的实例对象呢,而非接口实例呢,”
我发现你上面两句话很有问题:第一句表明我们已经有了一个ArrayList 的实例target,
但第二句话你又说想通过代理返回另一个ArrayList的实例,这样子转了一圈,得到还是原来的东西。
就好比:你已经有了一台xxx电脑,然后你把你的xxx电脑交给代理商,然后又要代理商返回一台xxx电脑,是要换新的?
如果真的要这样子做,从代理的原理上是很不通的,但是可以返回一个和ArrayList实例功能完全相同的实例,惟一差别就是这个实例不是ArrayList类型的。
下面是张老师ppt上说的:
动态代理方式:
1、JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作相同接口的目标类的代理。
如果某类没有实现接口,那虚拟机就没办法了。
2、但用CgLIB库可以CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,
所以,如果要为一个没有实现接口的类生成动态代理,那么可以使用CGLIB库。
结论:
1、两种方式的共同点是:代理类其实都是目标类的父类的子类;
因为代理类是目标类的父类的子类,那么代理类除了与目标类有共同的基本方法外,
还可以添加自己特有的方法,而这些特有方法功能就是代理类的意义所在了,
如果不添加一些特有功能,那么这个代理类就完全没意义了,因为他跟目标类的功能是一模一样,分毫不差。
2,代理类在父类基础上添加的功能就在:newProxyInstance()方法中的参数(InvocationHandler的子类的invoke()方法中),到底是怎么实现的我也清楚。
3,上面说:(代理类其实都是目标类的父类的子类),并不是很准确,因为产生成出的代理实例的类的父类是Proxy,这里采用这个说法来表达,是为了更容易理解一些;
API的解释:Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
另外,我认为动态代理的实现跟多态有一定的关系。
|