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.
or you can just use polymorphism…
Two classes instantiate base class over ride virtual (or whatever java equivalent of C++ virtual is). One prints a message another returns an enum. Do a switch on enum invoke a print of base class. Should be faster then relying on exception mechanism.
Well, yes you could use ordinary polymorphism. And in fact, I would in the real world. It is both faster and clearer. However, part of this exercise was in using the exception mechanism to achieve a different-than-normal result.
I originally, wanted to use exceptions as a mailbox (for a green thread), but when I typed out the above example, I realized that it still doesn’t allow processing the received messages out-of-order. An explicit queue is still required. However, it does get you a type-dispatch (poor man’s equivalent of pattern matching).
Turns out, exceptions can be used for many different tasks. Developers (including myself) are actually uncreative, in the sense that we tend to think exceptions are for error handling. When actually, the underlying mechanisms can be useful in other ways. The above post contains only one example (of many).