JAVA: What are the advantages of an InvocationHandler over an implementation of an Interface?

Proxy is a dynamic proxy, allowing you to alter the behaviour of objects at runtime instead of having to decide it at compile-time.

For example, let's say we want to return only nulls during the night. If you were to implement it statically, you would need to write the logic into all the classes with something like

if(isNight())
    return null;
return normalValue;

This requires that you can actually change the class, and you would need to change all the classes.

However with a Proxy, you can write the above logic into the InvocationHandler and the normal classes won't even know that their values aren't used during the night. Instead of the original class, your code is now using the dynamic proxy, but it won't know the difference.

This also allows you to have multiple InvocationHandlers, so you could run your code with parameters to decide if you want to log calls, prevent calls for security reasons, or any other such thing, which would be quite impossible to do with static implementations.


You're unlikely to use those classes directly though, as they're quite low level. However AOP uses either dynamic proxies or bytecode manipulation to achieve its task. If you've ever used Spring, you've most likely used an InvocationHandler without knowing it. When you put @Transactional on a method, an InvocationHandler is what will intercept the method call and start (and end) the transaction for you.


InvocationHandler together with Proxy allow implementation of an interface at runtime, without the faff of compiling interface-specfic code. It is often used to mediate access to an object of a class that implements the same interface. Proxy does not allow changing the behaviour of existing objects or classes.

For instance, it can be used in remote method calling on the client side, forwarding method call across a network to a server.

My first use of Proxy was for logging method calls to a wide interface that represented command received over a wire format. This easily produced very consistent debug output, but required little maintenance when the interface changed.

Java annotation interfaces may be represented by a Proxy proxy object at runtime, to prevent an explosion of classes.

java.beans.EventHandler was useful before lambdas and method references came along, to implement event listeners without bloating jars.


As per a more specific or real-world example, you may run into these kind of reflection usages more using a third-party or open-source API. A very popular example of this would be minecraft, specifically Bukkit/Spigot.

This api is used to write plugins, which the main server then loads and runs. This means you're not 100% in control of some of the code that exists in that codebase, inviting solutions using reflection. Specifically, when you want to intercept calls being made in the API (or even another plugin's API, e.g. Vault for those familiar), you may look to use a Proxy.

We'll stick with the minecraft example, but we're parting from bukkit's api here (and pretending it's not accepting PRs). Say there's a part of the API that just doesn't quite work the way you need.

public interface Player {
    //This method handles all damage! Hooray!
    public void damagePlayer(Player source, double damage);
}

This is great, but if we want to code something where we could find out if a player was damaged (maybe to make cool effects?), we'd need to modify the source (not possible for distributed plugins), or we'd need to find a way to figure out when #damagePlayer has been called and with what values. So in comes a Proxy:

public class PlayerProxy implements IvocationHandler {

    private final Player src;

    public PlayerProxy(Player src) {
        this.src = src;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        //Proceed to call the original Player object to adhere to the API
        Object back = m.invoke(this.src, args);
        if (m.getName().equals("damagePlayer") && args.length == 2) {
            //Add our own effects!
            //Alternatively, add a hook so you can register multiple things here, and avoid coding directly inside a Proxy
            if (/* 50% random chance */) {
                //double damage!
                args[1] = (double) args[1] * 2;
                //or perhaps use `source`/args[0] to add to a damage count?
            }
        }
    }
}

With our Proxy, we've effectively created a fake Player class, one which will simply call the methods in place for Player. If our PlayerProxy is invoked with myPlayerProxy.someOtherMethod(...), then it will happily pass along a call to myPlayerProxy.src.someOtherMethod(...) via reflection (the m#invoke in the method above).

Simply put, you hot-potato the objects in the library to suit your needs:

//we'll use this to demonstrate "replacing" the player variables inside of the server
Map<String, Player> players = /* a reflected instance of the server's Player objects, mapped by name. Convenient! */;
players.replaceAll((name, player) -> 
    (PlayerProxy) Proxy.newProxyInstance(/* class loader */, new Class<?>[]{Player.class}, new PlayerProxy(player)));

InvocationHandler can handle multiple interfaces too. By using a generic Object to pass along the invocations, you can then listen to a variety of different methods in the API all within the same Proxy instance.