Exception handling Exception Handling (Chapter 11) Sharma Chakravarthy Information Technology Laboratory (IT Lab) Computer Science and Engineering Department The University of Texas at Arlington, Arlington, TX 76019 Email: sharma@cse.uta.edu Course URL: https://wweb.uta.edu/faculty/sharmac Research URL: http://itlab.uta.edu/sharma Exception handling refers to handling errors at run time (not compile time) A large number of programming languages do not support exception handling Why is exception handling important? What happens if the language does not support exception handling? Any error at run time will terminate the program abnormally! Cannot even deal with errors that the developer suspects at run time Wrong input file name, wrong input value, Division by zero, 2 Exception handling (2) An exception is an object that is generated as a result of an error or an unexpected event. To prevent an exception from crashing your program, you must write code that detects and handles them With exception handling, a program can continue executing (rather than terminating) after dealing with a problem. Very important for Mission critical or business critical computing. Robust and fault tolerant programs (i.e., programs that can deal with problems as they arise and continue executing). 3 Exception: Examples ArrayIndexOutOfBoundsException occurs when an attempt is made to access an element past either end of an array. ClassCastException occurs when an attempt is made to cast an object that does not have an is-a relationship with the type specified in the cast operator. A NullPointerException occurs when a null reference is used where an object is expected. An ArithmeticException occurs when division by zero is attempted for integers (Note that a double division by zero results in +infinity or infinity) 4 1
Exception handling (2) Java s exception handling mechanism has three parts Defining the exception Raising (or throwing) the exception, and Handling the exception Let us first look at raising and handling exceptions as they are easier Defining exceptions is used by advanced programmers! Throwing Exceptions Exceptions are thrown (i.e., the exception occurs, or an exception is raised) when a method detects a problem inside its body and is unable to handle it. Stack trace information displayed when an exception occurs and is not handled. Information includes: The name of the exception in a descriptive message that indicates the problem that occurred The method-call stack (i.e., the call chain) at the time it occurred. Represents the path of execution that led to the exception method by method. This information helps you debug the program. 5 2
Handling Exception Now let us understand how we can detect these exceptions so that the program gives some meaningful output and terminates (or better yet, recovers if possible) This is done by including additional code around the statements that can throw exceptions An exception handler is a section of code that gracefully responds to exceptions when they are thrown The process of interpreting and responding to exceptions is called exception handling If your code does not handle an exception when it is thrown, the default exception handler deals with it (is invoked) The default exception handler prints an error message, stack trace, and terminates execution 10 You can have any number of catch blocks But, only one finally block which is optional Cannot have a try block without either catch or finally block 3
If an exception occurs in a try block, the try block terminates immediately and program control transfers to the first matching catch block (tries catch blocks sequentially in the order given and executes one or none) After the exception is handled, control resumes after the last catch block (to the finally block if there is one) Known as the termination model of exception handling. Some languages use the resumption model of exception handling, in which, after an exception is handled, control resumes just after the throw point. 4
If no exceptions are thrown in a try block, the catch blocks are skipped and control continues with the first statement after the catch blocks Either the final block if there is one Or continues with the next statement after all catch blocks The try block and its corresponding catch and/or finally blocks form a try statement. Please study the code given to you in projects to understand how exceptions are handled When a try block terminates, local variables declared in the block go out of scope. The local variables of a try block are not accessible in the corresponding catch blocks. When a catch block terminates, local variables declared within the catch block (including the exception parameter) also go out of scope. Any remaining catch blocks in the try statement are ignored, and execution resumes at the first line of code after the try catch sequence. A finally block, if one is present. object 5
Class hierarchy of collections framework Object Throwable Exception IOException EOFException LinkedFileNotFoundexception 22 Checked and Unchecked exceptions In Java, there are 2 categories of exceptions Checked and Unchecked Unchecked are those that inherit from the Error class or the RunTimeException class Exceptions from Error are thrown when critical error occurs, such as running out of memory you do not handle these conditions because conditions that cause them can rarely be dealt with in the program Checked and Unchecked exceptions (2) Also, the RunTimeException serves as a superclass for exceptions that result from programming errors, such as out of bounds array subscript It is best to avoid these exceptions rather than handle them; they can be avoided with properly written code Check for zero in a division Check for range in subscripting 23 24 6
Checked and Unchecked exceptions (3) All of the remaining exceptions (those that are not inherited from Error or RunTimeException) are checked exceptions You should handle checked exceptions in your program If the code in a method can potentially throw a checked exception, then the method must meet one of the following requirements It must handle the exception, or It must have a throws clause listed in the method header 25 Need to handle Checked exceptions import java.io.*; public class NoThrow //This file will not compile public static void displayfile(string name) //open file 8: FileReader freader = new FileReader(name); BufferedReader inputfile = new BufferedReader(freader); //read and display input files contents 11: String input = inputfile.readline(); while (input!= null) System.out.println(input); 14: input = inputfile.readline(); //close the file 17: inputfile.close(); public static void main(string[] args) displayfile("myfile.txt"); 26 Checked and Unchecked exceptions (3) Need to handle Checked exceptions import java.io.*; public class NoThrow //This file will compile public static void displayfile(string name) throws IOException //open file FileReader freader = new FileReader(name); BufferedReader inputfile = new BufferedReader(freader); //read and display input files contents String input = inputfile.readline(); while (input!= null) System.out.println(input); input = inputfile.readline(); //close the file inputfile.close(); public static void main(string[] args) displayfile("myfile.txt"); catch (IOException ioexception) System.out.println(" in catch in main"); System.out.println(ioexception); 27 28 7
When an exception is not caught When an exception is thrown, it cannot be ignored JVM searches for a compatible exception handler inside the method If none, control is passed to the previous method in the call stack If that also does not have an exception handler, it goes all the way to the main method If the main method does not handle the exception then the program is halted and the default exception handler is used to handle the exception The above is for unchecked exceptions. Checked exceptions need to be handled by the program 29 30 Need to handle Checked exceptions import java.io.*; public class NoThrow //This file will not compile public static void displayfile(string name) throws IOException //open file FileReader freader = new FileReader(name); BufferedReader inputfile = new BufferedReader(freader); //read and display input files contents String input = inputfile.readline(); while (input!= null) System.out.println(input); input = inputfile.readline(); //close the file inputfile.close(); public static void main(string[] args) displayfile("myfile.txt"); 31 32 8
Polymorphic references to Exceptions Recall that a reference variable of a superclass can reference subclass objects because of polymorphism When handling exceptions, you can use polymorphic references as a parameter in the catch clause For example, a catch clause that uses a parameter variable of the Exception type is capable of catching any exception that inherits from the Exception class For example NumberFormatException exception can be caught by the Exception catch clause number = Integer.parseInt(str) catch (Exception e) System.out.println( Conversion error: + e.getmessage()); works 33 Handling multiple Exceptions You can have multiple/several catch blocks with a try block When an exception is thrown by code in the try block, the JVM begins searching the try statement for a catch block that can handle the exception It searches from top to bottom and passes control of the program to the first catch block with a parameter that is compatible with the exception Note that only one catch block will be executed for each exception thrown Not including the polymorphic reference, a try statement may have only one catch clause for each specific type of exception 34 catch clauses have to be distinct number = Integer.parseInt(str) catch (NumberFormatException nfe1) System.out.println( Bad number format: + nfe.getmessage()); //ERROR! Cannot have two of the same catch (NumberFormatException nfe2) System.out.println(Str + is not a number ); 35 Specific before General The following is not allowed either. Gives a compilation error number = Integer.parseInt(str) catch (IllegalArgumentException iae) System.out.println( Bad number format: + nfe.getmessage()); //superclass exception before subclass exception is not allowed! catch (NumberFormatException nfe) System.out.println(Str + is not a number ); Because, NumberForamtException is a subclass of IllegalArgumentException class. The following is correct number = Integer.parseInt(str) catch (NumberFormatException nfe) System.out.println(Str + is not a number ); //subclass exception before superclass exception is fine catch (IllegalArgumentException iae) System.out.println( Bad number format: + nfe.getmessage()); 36 9
The finally block The try statement may have an optional finally block which, if present, must appear after all of the catch blocks The finally block is one or more statements that are always executed after the try block has executed and after any catch block has been executed if an exception was thrown The statements in the finally block execute whether an exception occurs or not You can use the finally block without using a catch block Java allows nested try/catch/finally statements 37 The finally block (2) The following style decouples try/catch and try/finally blocks //code that might throw exceptions finally //code for housekeeping //for example close file (in.close()) catch(ioexception e) //process exception and show errors 38 10
Recovering from Errors You can recover from some program errors using exception handlers (rather than giving a message for debugging and terminating the program) This is important as recovery catches and recovers from the errors so that the program can continue Wherever possible, the program should try to recover from the error and continue The code given for projects handles exceptions and recovers from some of them Now, let us see how we can recover from an error using exception handling readdata.java // determine if correct input file is provided if (args.length < 1) System.err.println("usage: java classname(e.g., Proj4test)" + " <file name in the same dir>"); System.exit(ABNORMAL_EXIT); input = new Scanner(new File(args[ZEROI])); catch(filenotfoundexception FNFE) System.err.printf("Could not find the input file %s\n", args[zeroi]); System.exit(ABNORMAL_EXIT); How can we rewrite this to recover from both errors? 43 44 11
readdata with recovery // determine if correct input file is provided cp = new Scanner(System.in); if (args.length < 1) System.out.println("Input Data file name was not supplied"); System.out.printf("Please input data file name: "); fname = cp.nextline(); else fname = args[zeroi]; // CHECK HOW recovery is done finput = openfile(fname); while (finput == null) System.out.printf("Error: %s %s", fname, " does not exist.\nenter correct file name: "); fname = cp.nextline(); finput = openfile(fname); public static Scanner openfile(string filename) Scanner sc = null; sc = new Scanner(new File(filename)); catch(filenotfoundexception FNFE) sc = null; finally return sc; 45 readdata with recovery (2) Similarly, the file processing can use an exception handler to check for NumberFormatException and pinpoint the input that raised the exception // start reading from data file // get total number of employees inputline = finput.nextline(); while (inputline.charat(base_index) == '/') inputline = finput.nextline(); numcomplexes = Integer.parseInt(inputLine); // more input data processing code catch (NumberFormatException nfe) System.out.println("I/O Error in File: " + fname + "\ncheck for: " + nfe.getmessage() + " and correct it!"); 46 Throwable method printstacktrace outputs the stack trace to the standard error stream. Helpful in testing and debugging. Throwable method getstacktrace retrieves the stacktrace information. Throwable method getmessage returns the descriptive string stored in an exception. To output the stack-trace information to streams other than the standard error stream: Use the information returned from getstacktrace and output it to another stream Use one of the overloaded versions of method printstacktrace Sometimes a method responds to an exception by throwing a different exception type that is specific to the current application. If a catch block throws a new exception, the original exception s information and stack trace are lost. Earlier Java versions provided no mechanism to wrap the original exception information with the new exception s information. This made debugging such problems particularly difficult. Chained exceptions enable an exception object to maintain the complete stack-trace information from the original exception. See example code in the book pages 465-466 (edition 8) 12
Throwing exceptions You can write code that throw one of the java standard exceptions, or an instance of a custom exception class that you have designed You can use a throw statement to throw an exception manually/explicitly. The general format is: throw new ExceptionType(String MessageString);//see Date class The throw statement creates an exception object to be created and thrown Don t confuse the throw statement with the throws clause. The throw statement causes an exception to be thrown or raised The throws clause informs the compiler that a method throws one of the exceptions Creating your own exception classes To meet the need of a specific class or an application, you can roll your own exception classes by extending the Exception class or one of its subclasses Use the @Exception tag in documentation comments (javadoc) Here is an example of creating your own exception and using it. 49 50 Creating exception classes (2) /* NegativeStartingBalance exceptions are thrown by the BankAccount class when a negative starting balance is passed to the constructor. */ public class NegativeStartingBalance extends Exception //This constructor uses a generic error message. public NegativeStartingBalance() super("error: Negative starting balance"); /** This constructor specifies the bad starting balance in the error message. @param The bad starting balance. */ public NegativeStartingBalance(double amount) super("error: Negative starting balance: " + amount); 51 Creating exception classes (3) // The BankAccount class simulates a bank account. public class BankAccount private double balance; // Account balance // This constructor sets the starting balance at 0.0. public BankAccount() balance = 0.0; System.out.println( Balance initialized to: 0.0\n ); /** This constructor sets the starting balance to the value passed as an argument. @param startbalance is the starting balance. @exception NegativeStartingBalance is thrown When startbalance is negative. */ public BankAccount(double startbalance) throws NegativeStartingBalance if (startbalance < 0) throw new NegativeStartingBalance(startBalance); balance = startbalance; See Date class for an example of throwing the RuntimeException 52 13
Creating exception classes (4) /** This program demonstrates how the BankAccount class constructor throws custom exceptions. */ public class AccountTest public static void main(string [] args) // Force a NegativeStartingBalance exception. try BankAccount account = new BankAccount(); account = new BankAccount(-100.0); catch(negativestartingbalance e) System.out.println(e.getMessage()); Output: Balance initialized to: 0.0 Error: Negative starting balance: -100.0 Miscellany Pre and Post conditions are used, respectively, for indicating conditions that need to be true before executing a method and conditions that need to be true after the method finishes executing This is useful for verifying the correctness of programs formally Assertions are conditions that should be true at the point they are asserted or specified Java supports assertions and throws AssertionError (a subclass of Error class) if the assertion statement evaluates to false 53 54 Miscellany (2) The form of Java assert statements is: 1. assert expression; which throws an AssertError if expression evaluates to false 2. assert expression1 : expression2; Which evaluates expression1 and throws an AssertionError with expression2 as the error msg if expression1 is false Scanner input - new Scanner(System.in); System,out.println( Enter a number between 20 and 30: ); int number = input.readln(); assert (number >= 20 && number <= 30) : incorrect input: + number; Miscellany (3) In SE 7, Java has introduced the multi catch statement to handle multiple exceptions in one catch catch (type1 type 2 type 3 e) IN SE 7, Java has also introduced try-with-resources alternative where you can acquire resources in the try block which are automatically released at the end of the try block. This can be used in lieu of using the finally block. Will show an exception if the input number is not in the range! 55 56 14
Summary Exception handling should be used for processing those infrequent errors which usually cause the program to terminate The operand of a throw statement can be any class derived from class Throwable (including your own extensions) When tostring() is invoked on any Throwable object, its resulting String includes the descriptive String that was supplied to the constructor A throws clause lists the exceptions that CAN be thrown by a method All non RuntimeException exceptions that a method can throw must be listed in that methods throws clause A method's checked exceptions need to be listed in that methods throws clause Summary (2) If a catch block cannot process the exception, or wants to let some other catch block also process it, the handler can rethrow the exception: catch(some_type X) <some code> throw X; // rethrowing the exception X Such a throw rethrows the exception to the calling block Exceptions thrown in constructors cause objects built as part of the object being constructed to be marked for eventual garbage collection 57 58 Summary (3) If the catch clause throws an exception (using the throw statement), then the execution is thrown back to the caller of this method. This happens after the finally block associated with that try (which generated the exception) is executed It is important to understand what statements you include in the finally block as this block is executed even if the return in the body is not executed Also, a finally block itself can throw an exception. If this happens then the original exception is lost and the new exception is thrown instead. Pay attention to what you write in the finally block This exception (from the finally block) needs to be caught by the outer try statement or the caller Thank You! 59 60 15