Sometimes we have a method that does nothing but throw an exception (after munging arguments a bit). For example:
static void fail(Bob bob, Fred fred, Exception cause) { throw new SadError(format( "Sorry, but {} and {} did not meet today", bob, fred), cause); }
Great when used as:
void friends(Bob bob, Fred fred) { try { meetAgain(bob, fred); } catch (MissedTrainException e) { fail(bob, fred, e); } }
But what about this?
PhoneNumber exchange(Bob bob, Fred fred { try { return beamBusinessCards(bob, fred); } catch (LostPhoneException e) { fail(bob, fred, e); return null; // Never reached } }
There's a neat generics trick to help:
static <R> R fail(Bob bob, Fred fred, Exception cause) { // Code unchanged - return ignored }
Now we can write:
PhoneNumber exchange(Bob bob, Fred fred { try { return beamBusinessCards(bob, fred); } catch (LostPhone e) { return fail(bob, fred, e); } }
The main downside is readability for the casual reviewer. Unless expecting this technique, he may think the new catch body returns a value. It may help to limit use to Exception
, forcing handling in the caller method, but not with RuntimeException
.
No comments:
Post a Comment