Bu, "Java'da Düşünme" den değiştirilmiş dinamik proxy örneğidir.Neden proxy.getClass() öğesini InvocationHandler's invoke() yönteminin içinde arayabilirim?
Yukarıdaki örnekteimport 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();
}
}
, I invoke()
yöntem içinde toString()
yöntemi arayın. Beklediğim gibi, sonsuz yineleme gerçekleşecek çünkü proxy'nin toString()
yöntemini çağırması İşleyiciyi tekrar çağırır.
Bu
Bruce Eckel "Java Düşünme" dedi nasıl: arayüz üzerinden çağrılar vekil aracılığıyla yönlendirilir, çünküinvoke()
iç vekil üzerindeki yöntemleri çağrılırken
Ancak dikkatli olun.
İstisna ayrıntıları:
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)
...
Ama proxy.toString();
için proxy.getClass();
yerine eğer:
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable {
proxy.getClass();
return method.invoke(proxied, args);
}
Herşey yolunda. StackOverflowError yok. Sonsuz özyineleme yok.
Ayrıca proxy.toString();
'u proxy.hashCode();
veya proxy.equals("foo");
ile değiştirmeyi denedim. StackOverflowError'a da neden oldular.
Neden getClass()
toString()
, hashCode()
ve equals()
farklı?
'getClass()' 'Obect' sınıfı tarafından uygulanan son bir yöntemdir. Bu aşırıya kaçmaz değil. – saka1029