This is a modified dynamic proxy example from "Thinking in Java".
import java.lang.reflect.*;
interface Interface { void foo(); }
class RealObject implements Interface {
public void foo() {}
}
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
@Override
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable {
proxy.toString();
return method.invoke(proxied, args);
}
}
public class ProxyTest {
public static void main(String args[]) {
RealObject real = new RealObject();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{ Interface.class },
new DynamicProxyHandler(real));
proxy.foo();
}
}
In above example, I call toString()
method inside invoke()
method. As I expected, infinite recursion will happen because calling proxy's toString()
method will invoke the Handler again.
This is how Bruce Eckel said in "Thinking in Java":
However, be careful when calling methods on the proxy inside
invoke()
, because calls through the interface are redirected through the proxy.
Exception details:
Exception in thread "main" java.lang.StackOverflowError
at DynamicProxyHandler.invoke(ProxyTest.java:19)
at $Proxy0.toString(Unknown Source)
at DynamicProxyHandler.invoke(ProxyTest.java:19)
at $Proxy0.toString(Unknown Source)
...
But, if I substitute proxy.getClass();
for proxy.toString();
:
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable {
proxy.getClass();
return method.invoke(proxied, args);
}
Everything is ok. No StackOverflowError. No infinite recursion.
I also tried to replace proxy.toString();
with proxy.hashCode();
or proxy.equals("foo");
. They caused StackOverflowError either.
Why getClass()
is different from toString()
, hashCode()
, and equals()
?
Aucun commentaire:
Enregistrer un commentaire