Why do we need exceptions? In C, return variables must be used to indicate errors: if((fd = fopen(path,...)) == -1){ if(errno==a){ ...} else if(errno==b){...} // other error code } // do something 1 Why do we need exceptions? • What are the problems with this? – This complicates the code by adding extra clutter to check the value of the return arguments. – If you have a function f() that calls g() that calls h(), and h() needs to return an error, both g() and f() have to contain special code to handle the exception 2 Why do we need exceptions? How does the code change when we add exceptions? try{ fd = new FileReader(path,...); } catch(IOException e){ // error code } catch(FileNotFoundException e){ // error code } // do something 3 When should exceptions be used? • Exceptions provide a way to signal errors without having to use return variables • They should generally be used when an unexpected error occurs • For example, Java uses an exception to signal when a file you are trying to open could not be found. • However, when searching for an item in an array, Java returns a -1 if it cannot find the item. 4 Checked Exceptions • You can either use one of the existing exceptions, or create your own • Most exceptions extend Exception, but a function can throw any class that extends Throwable • Such exceptions are known as checked exceptions – Functions that throw a checked exception must advertise this by using the throws keyword – Every function that calls a function that can throw an exception must either use a try…catch block or advertise that it throws the Exception with a throws keyword 5 Unchecked Exceptions • Unchecked exceptions do not need to be caught by your program. • There are two types: – Exceptions that extend Error are serious virtual machine errors, like OutOfMemoryError – Exceptions that extend RuntimeException can be caught, but do not need to be. These are problems like NullPointerException and IndexOutOfBoundsException 6 Using Exceptions In order to signal an error has occurred, your code must throw an exception: throw new MyException(“Error Message”) Also, all functions that throw exceptions must specifically state that they throw exceptions. A function that throws MyException and MyOtherException would be defined as follows: int myFunction() throws MyException, MyOtherException 7 Using Exceptions • A function that calls a function that can throw an exception must deal with it in one of two ways: – Advertise that it throws the exception – Use a try…catch block 8 Using Exceptions try{ fd = new FileReader(path,...); } catch(IOException e){ // error code } catch(Exception e){ // error code } 9 Exceptions and Inheritance • When creating a subclass, do not change the exceptions thrown by a method you override, unless you are changing them to a subclass of the previous exception. • However, you can remove one or more of the exceptions from the throws keyword. – If a method throws MyException and MyOtherException, a method that overrides it can throw only MyException 10 Finally… • When working with resources such as files or network connections, special handling is required for exceptions. • Resources often need to be properly closed to ensure that normal behavior continues, regardless of whether an exception will be thrown or not. 11 Why Finally? import java.io.*; class ProcessFile{ public static void main(String[] args){ if(args.length > 0){ FileReader f; try{ // Open a file: f = new FileReader(args[0]); SomeOtherClass.process(f); f.close(); } catch (IOException x){ System.out.println(x); if (f != null) f.close(); }}}} 12 Why Finally? import java.io.*; class ProcessFile{ public static void main(String[] args){ if(args.length > 0){ FileReader f; try{ // Open a file: f = new FileReader(args[0]); SomeOtherClass.process(f); } catch(IOException x){ System.out.println(x); } finally{ if(f != null) f.close(); }}} 13 SaM and Exceptions • Why do you need to know this? • In Part 2, your compiler will not have to throw exceptions. • However, you will be required to use SaMTokenizer • SamTokenizer can throw an exception when you request a token 14 SamTokenizer and Exceptions public int getInt() throws TokenizerException { if(next() == StreamTokenizer.TT_NUMBER) return (int)tokens.nval; else throw new TokenizerException("Attempt to read non-numerical value as an integer", lineNo()); } 15 Exceptions in your Project • All methods that use SamTokenizer, and any methods that call those methods, must advertise that they throw TokenizerException. • This will allow you to avoid handling the exceptions. • Under normal conditions, you should never get have a TokenizerException thrown, since you can check the type of the next token using peekAtKind() 16