读书人

InvocationHandler中invoke()方法的调

发布时间: 2012-09-04 14:19:30 作者: rapoo

InvocationHandler中invoke()方法的调用问题
以下的内容部分参考了网络上的内容,在此对原作者表示感谢!

首先,invoke方法的完整形式如下:


public final class $Proxy0 extends Proxy implements Subject {private static Method m1;private static Method m0;private static Method m3;private static Method m2;static {try {m1 = Class.forName("java.lang.Object").getMethod("equals",new Class[] { Class.forName("java.lang.Object") });m0 = Class.forName("java.lang.Object").getMethod("hashCode",new Class[0]);m3 = Class.forName("***.RealSubject").getMethod("request",new Class[0]);m2 = Class.forName("java.lang.Object").getMethod("toString",new Class[0]);} catch (NoSuchMethodException nosuchmethodexception) {throw new NoSuchMethodError(nosuchmethodexception.getMessage());} catch (ClassNotFoundException classnotfoundexception) {throw new NoClassDefFoundError(classnotfoundexception.getMessage());}} //staticpublic $Proxy0(InvocationHandler invocationhandler) {super(invocationhandler);}@Overridepublic final boolean equals(Object obj) {try {return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}@Overridepublic final int hashCode() {try {return ((Integer) super.h.invoke(this, m0, null)).intValue();} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}public final void request() {try {super.h.invoke(this, m3, null);return;} catch (Error e) {} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}@Overridepublic final String toString() {try {return (String) super.h.invoke(this, m2, null);} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}}


接着把得到的$Proxy0实例强制转换成Subject,并将引用赋给subject。当执行subject.request()方法时,就调用了$Proxy0类中的request()方法,进而调用父类Proxy中的h的invoke()方法.即InvocationHandler.invoke()。

PS:1、需要说明的一点是,Proxy类中getProxyClass方法返回的是Proxy的Class类。之所以说明,是因为我一开始犯了个低级错误,以为返回的是“被代理类的Class类”- -!推荐看一下getProxyClass的源码,很长=。=
2、从$Proxy0的源码可以看出,动态代理类不仅代理了显示定义的接口中的方法,而且还代理了java的根类Object中的继承而来的equals()、hashcode()、toString()这三个方法,并且仅此三个方法。

Q:到现在为止,还有一个疑问,invoke方法中的第一个参数是Proxy的实例(准确说,最终用到的是$Proxy0的实例),但是有什么用呢?或者说,程序内是怎样显示出作用的?
A:就本人目前的水平看来,这个proxy参数并没有什么作用,在整个动态代理机制中,并没有用到InvocationHandler中invoke方法的proxy参数。而传入的这个参数实际是代理类的一个实例。我想可能是为了让程序员在invoke方法中使用反射来获取关于代理类的一些信息吧。

读书人网 >软件架构设计

热点推荐