When you're in the middle of implementation, you want to be able to die() in unimplemented methods. But the Java mechanism for doing so is exceptions (just exiting isn't going to tell you what happened, why, and where), and exceptions require a lot of extra declarations and handling to implement. You don't want to declare that every single one of your unimplemented methods throws an unimplemented method exception. If you had that kind of time, you'd be using it to implement your methods. You don't want to catch and handle those methods in calling code. And most importantly, once your methods are implemented, you don't want to have to take the time and risk of removing all of those declarations and catch blocks.
The secret is that not all Java exceptions have to be declared and caught. Most of them do, yes, but early in the inheritance tree for exceptions a branch goes off called the RuntimeException. RuntimeExceptions are generally used for situations which could happen practically anywhere, without warning, rather than being specific to a particular method. You might try to dereference a null object, or go beyond the bounds of an array. That kind of thing doesn't need normal exception handling: it just needs to die() as we know it. And so if you want to die(), throw a RuntimeException.
Like most (all?) Exceptions, RuntimeException has a constructor which will accept a descriptive string that will somehow make its way to the user when the exception is thrown. So, turn:
die "Unimplemented method";
into:
throw new RuntimeException("Method not implemented");
Of course, if you wanted to honor the spirit of Java object-orientation, you could subclass RuntimeException, etc., etc. But then again, if you had that kind of time, you'd probably have implemented methods by now.