Java Reference
In-Depth Information
this leads to an invocation of the
invoke
method on the associated
De-
bugProxy
instance, passing
proxyObj
as the proxy object, a
Method
object
representing the method that was invoked, and all the arguments to the
method call. In our example
invoke
logs the invocation by adding it to its
list of invoked methods and then invokes the method on the underlying
realObj
object, which was stored in the
obj
field.
The (read-only) history of method invocations on the proxy object can
be retrieved from its
DebugProxy
instance. This is obtained by passing the
proxy to the static
Proxy
class method
getInvocationHandler
:
DebugProxy h =
(DebugProxy) Proxy.getInvocationHandler(proxyObj);
List<Method> history = h.getHistory();
If we hadn't used the
newProxyInstance
shortcut we would have needed
to write the following in
ProxyFor
:
Class<?> objClass = obj.getClass();
Class<?> proxyClass = Proxy.getProxyClass(
objClass.getClassLoader(),
objClass.getInterfaces());
Constructor ctor = proxyClass.getConstructor(
InvocationHandler.class);
return ctor.newInstance(new DebugProxy(obj));
The invocation handler's
invoke
method can throw
Throwable
. However, if
invoke
tHRows any exception that the original method could not throw,
the invoker will get an
UndeclaredThrowableException
that returns the of-
fending exception from its
getCause
method.
If you invoke
getProxyClass
twice with the same parameters (the same
class loader and the same interfaces in the same order) you will get
back the same
Class
object. If the interfaces are in another order or the
class loader is different, you will get back different
Class
objects. The