Dynamically adapts a given interface against a delegate object.
For the given {@code clazz} object, which should be an interface, we return a new dynamic
proxy object implementing that interface, which will forward all method calls made on the
interface onto the delegate object.
In practice this means that you can make it appear as though {@code delegate} implements the
{@code clazz} interface, without this in practice being the case. As an example, if you
create an interface representing the {@link android.media.MediaPlayer}, you could pass this
interface in as the first argument, and a real {@link android.media.MediaPlayer} in as the
second argument, and now calls to the interface will be automatically sent on to the real
media player. The reason you may be interested in doing this in the first place is that this
allows you to test classes that have dependencies that are final or cannot be easily mocked.
InvocationHandler invoke = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return delegate.getClass()
.getMethod(method.getName(), method.getParameterTypes())
.invoke(delegate, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
};
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, invoke);