Classic Java Method Dispatching Anger

Posted by Anders Fri, 18 May 2007 23:20:00 GMT

On a common trap that a lot of us have walked into as our Java skills deepened:

You’re solving some programming problem involving multiple types/classes when you realize that you can make great use of Java’s method overloading. Just implement one method for each of the classes, and you’re done! In this example, two subclasses of Person:

void doStuff(Worker worker) {
   ...
}
void doStuff(Capitalist capitalist) {
   ...
}

Now if you just call doStuff like this:

Person person = ...
x.doStuff(person);

it should all work, right? It should call the correct method, depending on which class person is. You probably feel a slight rush of pride when you look at how simple your solution is.

But of course it doesn’t work. Java’s method calls must have their argument types known at compile-time1. You need to have person cast to one of the subclasses, otherwise the compiler will complain that it doesn’t know which of the two methods you mean. You mean “either”, but the compiler can’t help you.

At this point there is often bitter disappointment and anger, usually directed at the compiler or language (“jävla skitspråk!”). Once that subsides, you know you have learned something. Even programmers with good knowledge of Java seem to walk into this trap, which is what made me notice this phenomenon. Even though you know all the theory of how Java works, you can still get surprised by the practical implications.

For me, it was around 1999 at my first job. I can’t remember the problem I was trying to solve, but I do remember the surprise and disappointment. I last witnessed it just a few weeks ago. When I mentioned the phenomenon to a friend, he recalled having gone through it himself, and also having witnessed it recently.

Does everyone go through this when they’re learning Java?

1 This doesn’t happen with dynamically typed languages, since they typically bind their methods at run-time. On the other hand most dynamically typed languages don’t do method dispatching on types at all. Some functional languages with fancier method dispatchers can do this stuff, maybe at the expense of slower method calls. Erlang’s pattern matching of messages takes this feature to the extreme (though it’s not exactly method calls). You could argue that Prolog is the very extreme of this, where everything is fancy method dispatching.

Posted in ,  | Tags ,  | 3 comments