Type-dispatch with Exceptions

I’m one of those Object Oriented programmers that consider type-inspection to be a design flaw. Much to my chagrin, I’ve found myself making occasional use of the Java instanceof keyword. In my most recent class lecture, we discussed Exceptions, and I later realized that one could essentially type-dispatch using the exception mechanism, because the catch blocks will trigger on the exception type. I experimented a bit, and discovered that this trigger behaves polymorphically (as I expected). I don’t know what use this is, other than a bit of craziness and verbosity.

First, we’ll create a hierarchy of messages:

public abstract class Message extends Throwable
{
    public abstract String contents();
}
 
public class PrivateMessage extends Message
{
    String msg = "";	
    public PrivateMessage(String msg) {
        this.msg = msg;
    }
 
    public String contents() {
        return "(private)" + msg;
    }
}
 
public class PrivateMessage extends Message
{
    String msg = "";	
        public PrivateMessage(String msg) {
        this.msg = msg;
    }
 
    public String contents() {
        return "(private)" + msg;
    }
}

Then we’ll create a Sender and Receiver to test out a message pass.

public class Sender
{
    public static void main(String[] args) {
        Receiver r = new Receiver();
        r.message(new PrivateMessage("hello"));
        r.message(new PublicMessage("world"));
    }
}
 
public class Receiver
{
    public void message(Message msg) {
        try {
            throw msg;
        } catch (PrivateMessage pm) {
            System.out.println("got a private message: " + pm.contents());
        } catch (PublicMessage pm) {
            System.out.println("got a public message: " + pm.contents());
        } catch (Message m) {
            System.out.println("unknown message:" + m.contents());
        }
    }
}

Lo, and Behold! when the program is run, we get the expected output:

got a private message: (private)hello
got a public message: (public)world

I really have no idea if this feature is useful or just crazy verbiage for what could easily have been a daisy-chain of instanceof tests. Java makes it especially complicated because you must extend the Throwable class, in order to implement the messages as exceptions. Perhaps in languages without runtime type inspection this pattern might come in useful.

Update 2011-01-23: My advisor forwarded me a 10yr old talk by Nigel Horspool which contains examples of exceptions used for ordinary control flow.