看TIJ的代理看得有点晕,其中有一段代码如下。(print是包装了下的System.out.println)
package TypeInfo;
// typeinfo/SimpleDynamicProxy23.java
// TIJ4 Chapter Typeinfo, Exercise 23, page 598
// Inside invoke() in SimpleDynamicProxy.java, try to print the proxy argument and explain
// what happens.
import java.lang.reflect.*;
interface Interface {
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface {
public void doSomething() { print("doSomething"); }
public void somethingElse(String arg) {
print("somethingElse " + arg);
}
}
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
* trying to print proxy leads to:
* StackOverFlowError
* at AbstractStringBuilder.(Unknown Source)
* at StringBuilder.(Unknown Source)
* at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java)
* at $Proxy0.toString(Unknown Source)
* at String.valueOf(Unknown Source)
* at StrinbBuilcer.append(Unknown Source)
* at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java), etc,
* probably due to infinite recursion because calls to toString()
* are passed repeatedly back to this invoke method
/
// System.out.println("proxy: " + proxy); // error
System.out.println("*** proxy: " + proxy.getClass() +
", method: " + method + ", args: " + args);
if(args != null)
for(Object arg : args)
System.out.println(" " + args);
return method.invoke(proxied, args);
}
}
代码比较容易看懂,但是其中的内在机制就很隐晦。调试时发现,consumer中调用Interface的方法后程序流直接就跳入了invoke。这是由什么机制决定的?换言之,在consumer中对接口Interface的方法的调用是如何转交给DynamicProxyHandler的invoke方法的?
书中有一句话:“在invoke()内部,在代理上调用方法时需要格外当心,因为对接口的调用将被重定向为对代理的调用。”这句解释了注释掉的“// System.out.println("proxy: " + proxy); // error”的错误是因为引起了无限递归(很空洞的解释,具体怎样引起?)invoke的第一个参数proxy是什么类型?
希望大家不吝赐教。3Q!
元芳怎么了
相关分类