Exceptions COMP 401 Prasun Dewan1 19 Exceptions So far we have been fairly lax about error handling in that we have either ignored errors or used a simple minded approach of terminating the program on encountering the first error Moreover error handling code was mixed with regular programming code Furthermore error messages to the user which belong to the user interface were mixed with computation code We will see how these problems can be overcome by using exceptions User Arguments Exception Handling Consider the following program which prints the first argument provided by the user package main public class AnArgPrinter public static void main String args System out println args 0 Figure 1 Printing a User Argument A problem with this program is that the user may have forgotten to supply an argument when executing the program Thus the value 0 provided as the index to args may be out of bounds Of course this is not what the program expects so it does perform correctly if the expected argument is supplied So what will happen if the unexpected case happens Some compilers including Java will automatically put code in the program to check if array subscripts are out of bounds and will terminate the program mentioning that the problem was a subscripting error Other less friendly but more efficient compilers do not bother to do so The program will compute an appropriate memory address where the element is expected and print whatever value is at that memory location If the memory address is outside the range of memory allocated to the program then it will dump core giving no hint of the problem 1 1 Copyright Prasun Dewan 2009 Exceptions None of these solutions are friendly to the users if the program who either get garbage printed out or are told about an subscripting error whose cause they probably cannot correlate with the actual error they committed or are given a core dump message Thus it is important for the programmer to detect the error and react appropriately to it We can of course use a conditional statement to explicitly check for the error if args length 0 System out println Did not specify the argument to be printed Terminating program System exit 1 else System out println args 0 However this solution mixes code handling of both the expected and exceptional cases making the program harder to understand and write The alternative code given in Figure 12 reduces this problem try System out println args 0 catch ArrayIndexOutOfBoundsException e System out println Did not specify the argument to be printed Terminating program System exit 1 Figure 2 Handling Exceptions It relies on the fact that the Java compiler does insert subscript checking code in the program It uses three related concepts exceptions throw bocks and catch blocks which we saw before when looking at user input When the code detects a subscripting error it throws an exception out of the try block which is then caught by the catch block written by the programmer More precisely it causes the program to jump out of the try block enclosing the statement that threw the exception and execute the catch block passing it an instance of the class ArrayOutOfBoundsException The catch block declares the class of the exception it expects to handle and receives as an argument any exception of this class that is thrown in the try block preceding it It can react appropriately to the exception In this example it prints for the user an error message indicating the cause of the problem 2 Exceptions In comparison to the previous solution this solution has the advantage that the expected and exceptional cases are clearly delineated making it possible to implement and understand the code in two passes In the first pass we can worry about the excepted cases and later in the second pass we can address the exceptional cases There are several other advantages of exceptions which we will see when we study them in more detail Separating error detection and handling Consider the following code package main import java io BufferedReader import java io InputStreamReader import java io IOException public class AnArgsPrinter static BufferedReader inputStream new BufferedReader new InputStreamReader System in public static void main String args echoLines numberOfInputLines args static int numberOfInputLines String args try return Integer parseInt args 0 catch ArrayIndexOutOfBoundsException e System out println Did not enter an argument return 0 static void echoLines int numberOfInputLines try for int inputNum 0 inputNum numberOfInputLines inputNum System out println inputStream readLine catch IOException e System out println Did not input numberOfInputLines input strings before input was closed System exit 1 3 Exceptions It is an extension of the previous code that echoes multiple lines The number of lines to be input is specified as the first argument As before if this argument is not specified a subscript exception is thrown and the user is given an error message Recall that a user can close input by entering an EOF End of File indicator If a program tries to read a closed input stream Java throws an IOException In this example such an exception would be thrown if the user closes input before entering the expected lines of input Therefore the catch block of this exception gives an appropriate error message Though this example uses exception handlers it still is not perfectly satisfactory The function getNumberOfInputLines must provide a return value and so it chooses an arbitrary value which cannot be distinguished from a value actually entered by the user Moreover the function is responsible for both computing the number of lines and user interface issues Error messages really belong to the user interface as there are multiple ways to report errors In our example they could be reported in the system transcript or a dialogue box Also echoLines and getNumberOfLines make different decisions regarding what to do with an error echoLines halts the program while getNumberOfLines decides to return to the caller If they have been written independently such non uniformity was to be expected More important neither of them has enough context to make the right decision The problem seems to be that error detection and handling are coupled here that is done by one method The solution is to handle errors not in these two methods but in the main method The two methods are the ones that detect the errors so they need a way to communicate the detected errors to
View Full Document
Unlocking...