Overloading in Java and multiple dispatch

This post seconds voo’s answer, and gives details about/alternatives to late binding.

General JVMs only use single dispatch: the runtime type is only considered for the receiver object; for the method’s parameters, the static type is considered. An efficient implementation with optimizations is quite easy using method tables (which are similar to C++’s virtual tables). You can find details e.g. in the HotSpot Wiki.

If you want multiple dispatch for your parameters, take a look at

  • groovy. But to my latest knowledge, that has an outdated, slow multiple dispatch implementation (see e.g. this performance comparison), e.g. without caching.
  • clojure, but that is quite different to Java.
  • MultiJava, which offers multiple dispatch for Java. Additionally, you can use
    • this.resend(...) instead of super(...) to invoke the most-specific overridden method of the enclosing method;
    • value dispatching (code example below).

If you want to stick with Java, you can

  • redesign your application by moving overloaded methods over a finer grained class hierarchy. An example is given in Josh Bloch’s Effective Java, Item 41 (Use overloading judiciously);
  • use some design patterns, such as Strategy, Visitor, Observer. These can often solve the same problems as multiple dispatch (i.e. in those situations you have trivial solutions for those patterns using multiple dispatch).

Value dispatching:

class C {
  static final int INITIALIZED = 0;
  static final int RUNNING = 1;
  static final int STOPPED = 2;
  void m(int i) {
    // the default method
  }
  void m(int@@INITIALIZED i) {
    // handle the case when we're in the initialized `state'
  }
  void m(int@@RUNNING i) {
    // handle the case when we're in the running `state'
  }
  void m(int@@STOPPED i) {
    // handle the case when we're in the stopped `state'
  }
}

Leave a Comment