Exceptions: When Things Go Wrong

It is not a matter of IF but WHEN things will go wrong in a computer program. Sometimes there are bugs, errors of one form or another. There also also unforeseen use cases. You can never assume a computer program is perfect. Exception-Handling helps us to catch erroneous events and devise means of correcting them. We discuss this topic here since exception-handling can take more code than should be put into the main line of execution. In such cases, a method in an exception-handling class should be called. Exception handling mechanisms allow a program to continue executing, instead of terminating it abruptly, even if an error occurs in the program.

10.4 Handling Exceptions Within a Progr

Dynamic Versus Static Scoping

How does Java know that it should execute the catch clause in CalcAvgTest.main() when an exception is thrown in avgFirstN()? Also, doesn’t the latest version of avgFirstN() (Fig. 10.7) violate the restriction that a throw statement must occur within a try block?

An exception can only be thrown within a dynamically enclosing try block. This means that the throw statement must fall within the dynamic scope of an enclosing try block. Let’s see what this means.

Dynamic scoping refers to the way a program is executed. For example, in CalcAverage (Fig. 10.7), 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.

Contrast dynamic with what you have learned about static scope, which we’ve used previously to define the scope of parameters and local variables (Fig. 10.10). Static scoping refers to the way a program is written. A statement or variable occurs within the scope of a block if its text is actually written within that block. For example, consider the definition of MyClass (Fig. 10.11). The variable X occurs within the (static) scope of method1(), and the variable Y occurs within the (static) scope of method2().

Annotation 2020-03-29 170955

A method’s parameters and local variables occur within its static scope. Also, in the 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.

Dynamic scoping can only be determined by running the program. For example, in MyClass the order in which its statements are executed depends on the result of 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

Annotation 2020-03-29 171232

“Hello2.” In that case, the statement System.out.println("Hello" + Y) has the following dynamic scope:

Annotation 2020-03-29 171335

It occurs within the (dynamic) scope of 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.