- Exceptions in Java
- Using Exceptions To Write Elegant Code
- The Problem: Using Exceptions for Control-Flow
- Performance Tests of the Two Code Samples
- Summary
Using Exceptions To Write Elegant Code
Exceptions provide a way to write elegant code by keeping rare situations from cluttering up the rest of the code, thereby improving readability.
We would never use the exception from Listing 1 by checking for the exceptions individually, as in Listing 2:
Listing 2
int x = 1, y = 1; // avoids warnings about uninitialized variables try { x = Integer.parse(args[0]); } catch (ArrayIndexOutOfBoundsException ae1) { System.out.println(usageString); } try { y = Integer.parse(args[1]); } catch (ArrayIndexOutOfBoundsException ae2) { System.out.println(usageString); } try { testMe(x, y); System.out.println("The result is " + x/y); } catch (Exception ex) { } finally { System.out.println(thanksString); System.exit(); } // ...
It's much better and easier to collect the exceptions at the end of the code. In this example, we could have done a quick if check to see whether the number of arguments match the expected value. But in more involved cases we may need several such checks in different places, and they tend to clutter up the code. Also, in some cases, the issues may be within called methods, and we may have to transfer the error situation up a chain.
In some cases, it may be much more readable and effective to collect all exceptions at the end of the block. This works even better if the thrown exception object is an instance of a subclass used for all exceptions. We could hold the type of exception as one of the attributes of the object, and use that in the handler to take appropriate action. Such techniques result in more readable code, as shown in Listing 3.
Listing 3
try { Object o = readInput(); AnalyzeHeader(o); OutputHeader(o); AnalyzeBody(o); OutputBody(o); AnalyzeFooter(o); OutputFooter(o); } catch (MyException mEx) { switch(mEx.getCode()) { case 1: System.out.println("Bad input"); break; default: System.out.println(mEx); } }