Principle 10.4.3. EFFECTIVE DESIGN: Using an Exception.
Unless your program’s handling of an exception is significantly different from Java’s default handling of it, the program should just rely on the default.

avgFirstN() example, the typical way of handling this error in Java would be to throw an exception in the avgFirstN() method and catch it in the calling method. Of course, the calling method could be in the same object or it could belong to some other object. In the latter case, the detection of the error is separated from its handling. This division of labor opens up a wide range of possibilities. For example, a program could dedicate a single object to serve as the handler for all its exceptions. The object would be sort of like the program’s fire department.
try/throw/catch mechanism, let’s revisit the CalcAvgTest program. The version shown in Listing 10.4.2 mimics the way Java’s default exception handler works. If the avgFirstN() method is called with an argument that is zero or negative, an IllegalArgumentException is thrown. The exception is caught by the catch clause in the CalcAvgTest.main() method.
try {
CalcAverage ca = new CalcAverage();
System.out.println( "AVG + " + ca.avgFirstN(0));
}
catch (IllegalArgumentException e) { // Exception Handler
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(0);
}
calcAvgTest program, an IllegalArgumentException thrown in CalcAverage.avgFirstN(), would be handled by the catch clause in CalcAvgTest.main().CalcAverage.avgFirstN() method has a zero or negative argument, it will throw an exception:
if (N <= 0)
throw new IllegalArgumentException("ERROR: Illegal argument");
throw statement. It creates a new IllegalArgumentException object and passes it a message that describes the error. This message becomes part of the exception object. It can be retrieved using the getMessage() method, which is inherited from the Throwable class (Figure 10.3.1).
throw statement is executed, the JVM interrupts the normal execution of the program and searches for an exception handler. We will describe the details of this search shortly. In this case, the exception handler is the catch clause contained in the CalcAvgTest.main() method:
catch (IllegalArgumentException e) { // Exception Handler
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(0);
}
IllegalArgumentException is thrown, the statements within this catch clause are executed. The first statement uses the getMessage() method to print a copy of the error message. The second statement uses the printStackTrace() method, which is defined in Throwable and inherited by all Exception s, to print a trace of the method calls leading up to the exception. The last statement causes the program to terminate.
ERROR: Can't average 0 elements
java.lang.IllegalArgumentException: ERROR: Illegal argument
at java.lang.Throwable.fillInStackTrace(Native Method)
at java.lang.Throwable.<init>(Throwable.java:94)
at java.lang.Exception.<init>(Exception.java:42)
at java.lang.RuntimeException.<init>
(RuntimeException.java:47)
at java.lang.IllegalArgumentException.<init>
(IllegalArgumentException.java:43)
at CalcAverage.avgFirstN(Compiled Code)
at CalcAvgTest.main(CalcAvgTest.java:5)
catch clause is associated with a try block. The handling of exceptions in Java takes place in two parts: First, we try to execute some statements, which may or may not lead to an exception. These are the statements contained within the try clause:
try {
CalcAverage ca = new CalcAverage();
System.out.println( "AVG + " + ca.avgFirstN(0));
}
catch clauses to handle particular types of exceptions. In this case, we are only handling IllegalArgumentException s.
try block. The “fire department” in this case is the code contained in the catch clause that immediately follows the try block. This is the exception handler for this particular exception. There’s something like a game of catch going on here: Some method within the try block throws an Exception object, which is caught and handled by the catch block located in some other object (Figure 10.4.4).

IllegalArgumentException is thrown by the CalcAverage.avgFirstN() method and caught by the catch clause within CalcAvgTest.main() method.CalcAvgTest example, an important difference between Java’s exception handling and more traditional approaches is that error handling can be separated from the normal flow of execution within a program. The CalcAverage.avgFirstN() method still checks for the error and it still throwsIllegalArgumentException if N does not satisfy the method’s precondition. But it does not contain code for handling the exception. The exception-handling code is located in the CalcAvgTest class.
CalcAvgTest program creates a clear separation between the normal algorithm and the exception-handling code. One advantage of this design is that the normal algorithm is uncluttered by error-handling code and, therefore, easier to read.
CalcAvgTest.main(), one exception handler can be used to handle other errors of that type. For example, this catch clause could handle allIllegalArgumentException s that get thrown in the program. Its use of printStackTrace() will identify exactly where the exception occurred. In fact, because a Java application starts in the main() method, encapsulating all of a program’s executable statements within a single try block in the main() method will effectively handle all the exceptions that occur within a program.
try followed by a block of code enclosed within curly braces. A catch clause or catch block consists of the keyword catch, followed by a parameter declaration that identifies the type of Exception being caught, followed by a collection of statements enclosed within curly braces. These are the statements that handle the exception by taking appropriate action.
try {
// Block of statements
// At least one of which may throw an exception
if ( /* Some condition obtains */ )
throw new ExceptionName();
} catch (ExceptionName ParameterName) {
// Block of statements to be executed
// If the ExceptionName exception is thrown in try
} catch (ExceptionName2 ParameterName) {
// Block of statements to be executed
// If the ExceptionName2 exception is thrown in try
... // Possibly other catch clauses
} finally {
// Optional block of statements that is executed
// Whether an exception is thrown or not
}
catch block that matches the particular kind of exception that was thrown. Exceptions are thrown by using the throw statement, which takes the following general form:
throw new ExceptionClassName(OptionalMessageString);
throw is followed by the instantiation of an object of the ExceptionClassName class. This is done the same way we instantiate any object in Java: by using the new operator and invoking one of the exception’s constructor methods. Some of the constructors take an OptionalMessageString, which is the message that gets returned by the exception’s getMessage() method.
catch block has the following general form:
catch (ExceptionClassName ParameterName) {
// Exception handling statements
}
catch block is very much like a method definition. It contains a parameter, which specifies the class of exception that is handled by that block. The ParameterName can be any valid identifier, but it is customary to use e as the catch block parameter. The parameter’s scope is limited to the catch block, and it is used to refer to the caught exception.
ArithmeticException is thrown, it will match both an ArithmeticException parameter and an Exception parameter, because ArithmeticException is a subclass of Exception.
catch clauses associated with a given try block, and the order with which they are arranged is important. A thrown exception will be caught by the first catch clause it matches. Therefore, catch clauses should be arranged in order from most specific to most general (See the exception hierarchy in Figure 10.3.1). If a more general catch clause precedes a more specific one, it will prevent the more specific one from executing. In effect, the more specific clause will be hidden by the more general one. You might as well just not have the more specific clause at all.
ArithmeticException is thrown in the following try/catch statement:
try {
// Suppose an ArithmeticException is thrown here} catch (ArithmeticException e) {
System.out.println("ERROR: " + e.getMessage() );
e.printStackTrace();
System.exit(1);} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage() );
}
ArithmeticException block. On the other hand, if some other kind of exception is raised, it will be caught by the second catch clause. The Exception class will match any exception that is thrown. Therefore, it should always occur last in a sequence of catch clauses.
Exception clause should always be the last in the sequence.
try/catch/finally Statement
throw statement is used to throw both checked exceptions and unchecked exceptions, where unchecked exceptions are those belonging to RuntimeException or its subclasses. Unchecked exceptions need not be caught by the program.
throw statement must be contained within the dynamic scope of a try block, and the type of Exception thrown must match at least one of the try block’s catch clauses. Or the throw statement must be contained within a method or constructor that has a throws clause for the type of thrown Exception.
catch clause in CalcAvgTest.main() when an exception is thrown in avgFirstN()? Also, doesn’t the latest version of avgFirstN()(Listing 10.4.2) violate the restriction that a throw statement must occur within a try block?
throw statement must fall within the dynamic scope of an enclosing try block. Let’s see what this means.
CalcAverage(Listing 10.4.2), the avgFirstN() method is called from within the try block located in CalcAvgTest.main(). Thus, it falls within the dynamic scope of that try block.

MyClass(Listing 10.4.11). The variable X occurs within the (static) scope of method1(), and the variable Y occurs within the (static) scope of method2().
MyClass definition, the System.out.println() statements occur within the static scope of method1() and method2(), respectively. In general, static scoping refers to where a variable is declared or where a statement is located. Static scoping can be completely determined by just reading the program.
Math.random(). Suppose that when random() is executed it returns the value 0.99. In that case, main() will call method2(), which will call System.out.println(), which will print “Hello2.” In that case, the statement System.out.println("Hello" + Y) has the following dynamic scope:
main()
method2()
System.out.println("Hello" + Y);
method2(), which is within the (dynamic) scope of main(). On the other hand, if the result of random() had been 0.10, that particular println() statement wouldn’t have been executed at all. Thus, to determine the dynamic scope of a particular statement, you must trace the program’s execution. In fact, this is what the printStackTrace() method does. It prints a trace of a statement’s dynamic scope.

Propagate program. The curved arrows give a trace of the method calls leading to the program’s present state.CalcAvgTest() example (Listing 10.4.2), Java would search backward to the CalcAvgTest.main() method, which is where avgFirstN() was called, and it would find the catch clause there for handling IllegalArgumentException s. It would, therefore, execute that catch clause.
ArrayIndexOutOfBoundsException. Using the exception hierarchy in Figure 10.3.1, determine which of the following catch clauses could handle that exception.
catch (RunTimeException e)
RunTimeException is a superclass of ArrayIndexOutOfBoundsException.catch (StringIndexOutOfBoundsException e)
catch (IndexOutOfBoundsException e)
IndexOutOfBoundsException is a superclass of ArrayIndexOutOfBoundsException.catch (Exception e)
catch (ArrayStoreException e)
random() is called it returns 0.98, and the second time it is called it returns 0.44. What output would be printed by the program? What would be output if printStackTrace() were called in addition to printing an error message? public class MyClass2 {
public void method1(double X) {
if (X > 0.95)
throw new ArithmeticException(X
+ " is out of range");
System.out.println("Hello " + X);
}
public void method2(double Y) {
if (Y > 0.5)
throw new ArithmeticException(Y
+ " is out of range");
System.out.println("Hello " + Y);
}
public static void main(String argv[]) {
MyClass2 myclass = new MyClass2();
try {
myclass.method1(Math.random());
myclass.method2(Math.random());
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
} // main()
} // MyClass2
MyClass2 program above, suppose that the first time random() is called it returns 0.44, and the second time it is called it returns 0.98. What output would be printed by the program? What would be output if printStackTrace() were called instead of printing an error message.
public class BadDivide {
public void method1 (int n) {
method2(100, n);
}
public void method2 (int n, int d) {
System.out.println(n / d);
}
public static void main(String args[]) {
BadDivide bd = new BadDivide();
for (int k = 0; k < 5; k++)
bd.method1(k);
}
}
method2() so that it handles the divide-by-zero exception itself, instead of letting Java handle it. Have it print an error message and a stack trace.
someValue equals 1000? int M = someValue;
try {
System.out.println("Entering try block");
if (M > 100)
throw new Exception(M + " is too large");
System.out.println("Exiting try block");
} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
someValue equals 50?
try/catch block that throws an Exception if the value of variable X is less than zero. The exception should be an instance of Exception and, when it is caught, the message returned by getMessage() should be “ERROR: Negative value in X coordinate.”