Overview Exceptions Why Exceptions? • Exceptions allow the programmer to treat error conditions outside the main logic flow • Most programming languages (without exceptions) handle errors by passing return codes as error indicators • Why Exceptions? • Working with methods that throw exceptions • The try-catch-finally block • The class Exception and its subclasses • Checked vs Unchecked Exceptions • Defining your own Exceptions What’s an Exception • A signal that indicates an exceptional condition (something unexpected) has happened in your program • To throw an exception is to signal that an exceptional condition has occurred • To catch an exception is to handle the exception - to take whatever action is necessary – sometimes you can’t do anything Working with methods that throw exceptions Exception Example 1 the FileInputStream class constructor public FileInputStream (String s) throws FileNotFoundException; String s = “myfile.dat”; FileInputStream fis = new FileInputStream (s); will not compile unless… we deal with the possibility of an Exception Exception Example 2 the Thread class may throw exception try { FileInputStream fis = new FileInputStream (s); } catch (FileNotFoundException e) { } Thread static method public static void sleep (long millis) throws InterruptedException; Thread.sleep(1000); will not compile unless…. Exception Example 2 [catching the exception] Thread static method public static void sleep (long millis) throws InterruptedException; try { Thread.sleep(1000); } catch (InterruptedException e) { } Handling Exceptions... C:\class\Programs\Exceptions\ExceptTest.java:6: Exception java.io.FileNotFoundException must be caught, or it must be declared in the throws clause of this method. • Catch the exception in our method OR • List the exception in our own method header quick way to play with code that throws exceptions Exception Example 2 [catching the exception] Thread static method public static void sleep (long millis) throws InterruptedException; OR .. can catch a superclass of the Exception class try { Thread.sleep(1000); } catch (Exception e) { } Throwable Exception InterruptedException class ThreadSleepTest { public static void main (String [] args) throws InterruptedException { } for (int i=0; i< 10; i++) { if ( i == 5) Thread.sleep(1000); System.out.print(i + ".. "); } >java ThreadSleepTest 0.. 1.. 2.. 3.. 4.. 5.. 6.. 7.. 8.. 9.. one second pause try-catch the complete story class ThreadSleepTest2 { public static void main (String [ ] args) { try { for (int i=0; i< 10; i++) { if ( i == 5) Thread.sleep(2000); System.out.print(i + ".. "); } } catch (InterruptedException e) { } try { // code that might // throw an exception } catch (ExceptionType variable) { // handle the exception if thrown } finally { // .. always do this } } // assume t is a thread object try { t.sleep(1000); } catch (InterruptedException e) { System.out.println(“an exceptions was thrown”); } finally { System.out.println(“finally”); } Used for cleanup close files, release resources... Try..Catch..Finally Combo Rules • You cannot use try alone • A try block requires catch or finally or both • A catch or finally block requires a try block • The finally block is always executed as part of the Java control flow – even if you use a return or break to avoid a finally block Catching multiple exceptions • You may have multiple catch blocks associated with one try block try { someObject.test(); anotherObject.foo(); } catch (InterruptedException e1) { // do something with e1 } catch (IOException e2) { // do something with e2 } catch (NullPointerException e3) { // do something with e3 } You must use a different parameter name. All are in the same scope An exception is handled by the first catch block with a type match The Exception Hierarchy The Exception Hierarchy public String getMessage( ) public void printStackTrace ( ) A Java exception is an object that is an instance of some subclass of Throwable includes a String message that is inherited by all subclasses Throwable Error Errors are exceptions that result from system problems (e.g. Java Virtual Machine) Errors are almost always unrecoverable - should not be caught The Exception Hierarchy Throwable Exception Conditions that may be caught and handled Error A user defined exception should subclass Exception Often recoverable Exception UserDefinedException Using Methods from Throwable try { t.sleep(1000); Throwable } catch (InterruptedException e) { System.out.println(e.getMessage() ); e.printStackTrace(); } finally { System.out.println(“finally”); } What Exceptions Must be Caught? Exception InterruptedException Checked Exceptions those that the compiler checks that you’ve handled UnChecked Exceptions Throwable Throwable unchecked errors unchecked exceptions Error Error Exception RuntimeException AnyOtherSubclass Checked exceptions Must be caught!! Unchecked Exceptions Exception RuntimeException ArithmeticException IndexOutOfBoundsException The programmer is not required to catch these -- although they may crash your program public void foo (int k ) { foo (0); public void foo (int k ) { int j=1; foo (0); int j=1; System.out.println( j / k ); } try { System.out.println( j / k ); } catch (ArithmeticException e) { System.out.println(“Some idiot passed a zero”); } Unchecked Exception is thrown if k = 0 Program aborts with message: Program does not abort Java.lang ArithmeticException: / by Zero } public void foo (int k ) { Error int j=1; not a good class name - all exceptions occur at runtime Exception if (k==0) { System.out.println(“Some idiot passed a zero”); } else { System.out.println( j / k ); } Program does not abort } Exception Subclasses Throwable foo (0); RuntimeException ArithmeticException IndexOutOfBoundsException NegativeArraySizeException AWTException Must be caught in try..catch block or passed on…. InterruptedException Exceptions not used... IOException class ExceptionPropagateTest { public static void main (String args [ ] ) { Exceptions Travel Up the Call Stack foo (); } public static void foo () { bar (); } public static void bar () { int j=1, k=0; program aborts main foo bar System.out.println( j / k ); } } exception looking for a catch block When Checked Exceptions get Thrown class ExceptionPropagateTest { public static void main (String args [ ] ) { foo (); } public static void foo () { An exception may be try { bar (); } caught anywhere in catch (ArithmeticException e) { the calling stack System.out.println("Caught it in foo "); } } Programmer Options This program terminates normally public static void bar () { int j=1, k=0; System.out.println( j / k ); } } NOTE: the compiler does not require you to catch this unchecked exception (catch or pass the buck) Option 1 for Checked Exceptions Option 2 for Checked Exceptions Option 1. - catch it! may throw a public void foo() { checked exception try { t.sleep(1000); } catch (InterruptedException e) { System.out.println(“can’t sleep”); } } • Option 2. - explicitly rethrow the exception void foo() throws InterruptedException { try { t.sleep(1000); } catch (InterruptedException e) { // do something locally then. count++; throw(e); now the caller of } } foo( ) must beware!! void foo() throws InterruptedException Option 3 for Checked Exceptions Option 3. - pass the buck - implicitly void bar () { // some code try { foo (); } catch (InterruptedException e) { System.out.println(“oops! ”); } // some more code } void foo() throws InterruptedException { t.sleep(1000); } the compiler knows that some method will handle the exception!! any caller of foo( ) must either catch or pass the buck! Throwing Unchecked Exceptions • Unchecked Exceptions – A method may throw any unchecked exception – No requirement to declare anything in the method declaration Throwing Exceptions void foo() { if (…) throw new ArithmeticException (); if (…) throw new IndexOutOfBoundsException (); } Throwing Checked Exceptions • Checked Exceptions – A method may throw any checked exception as long as either: • the exception class is declared in the method throws clause • a superclass of the exception class is declared in the method throws clause void foo (int i) throws Exception { if (i == 0) throw new IOException(); } Exception OR… you may declare a superclass of the exception type you throw IOException not good practice but allowed by Java’s rules for subclass substitution void foo (int i) throws IOException { if (i == 0) throw new IOException(); } you must declare the type of any checked exception you throw … OR throw - catch parameter matching void bar () { try { foo(4); } catch (IOException e) { } } the catch clause MUST specify a compatible type with throws header void foo (int i) throws IOException { if (i == 0) throw new IOException(); } throw - catch parameter matching throw - catch parameter matching void bar () { try { foo(4); } catch (Exception e) { } } this will compile but is poor programming practice! void bar () { compiler will try { not allow this! foo(4); } catch (IOException e) { } } void foo (int i) throws IOException { if (i == 0) throw new IOException(); } void foo (int i) throws Exception { if (i == 0) throw new IOException(); } Compiler: Exception java.lang.Exception must be caught Multiple Catch Blocks.. Multiple Catch Blocks..GOTCHA! try { checked in order until match is found! someObject.test(); anotherObject.foo(); } catch (InterruptedException e1) { // do something with e1 } catch (IOException e2) { // do something with e2 try { someObject.test(); anotherObject.foo(); } catch (Exception e1) { // do something with e1 } catch (IOException e2) { // do something with e2 } catch (NullPointerException e3) { } catch (NullPointerException e3) { // do something with e3 // do something with e3 } } Multiple Catch Blocks try { someObject.test(); list most specific anotherObject.foo(); Exceptions first } catch (IOException e1) { // do something with e1 } catch (NullPointerException e2) { // do something with e2 } catch (Exception e3) { // do something with e3 } matches ALL Exceptions and subclasses of Exception list most general Exceptions last Creating Your Own Exception Classes Creating Your Own Exception Class • extend the class Exception • take advantage of the Exception class constructor throwing your exception You throw an exception by combining the keyword throw with object creation: – Exception (String s) • the string can be retrieved by sending getMessage() to the exception object throw new MyException(“MyException ZZ”); public class MyException extends Exception { // constructor public MyException (String s) { super(s); // calls the superclass constructor } } public class A { public static void main(String args []) { A myObj = new A(); try { myObj.test(); } catch (Exception e) { System.out.println(e.getMessage() ); } } void test () throws MyException { throw new MyException("hey"); } } this can be a very specific message hey How should you handle Exceptions? class MyException extends Exception { MyException (String s) { super(s); // calls the superclass constructor } you must call the superclass’ constructor } FileInputStream in = new FileInputStream(“employee.dat”); do we need to catch exceptions here? Ask the compiler, AND/OR Look up the method declarations public FileInputStream (String name) throws FileNotFoundException; requires a design decision how to handle if NOT a subclass of RuntimeException Options • • • • • Do nothing .. ignore it Print a message and bail out Pass the buck Get some new information and retry Pass an application-specific exception back to the caller Do Nothing try { FileInputStream in = new FileInputStream(“employee.dat”); } catch (FileNotFoundException e) {} compiler is happy but programmer may spend hours trying to debug the program Print and Bail try { Print and Rethrow try { FileInputStream in = new FileInputStream(“employee.dat”); } FileInputStream in = new FileInputStream(“employee.dat”); } catch (FileNotFoundException e) { catch (FileNotFoundException e) { System.out.println (“can’t find employee.dat file”); System.out.println (“can’t find employee.dat file”); System.exit(1); } throw e; } “print a message and bail out” Pass the Buck “print a message and let the calling method handle it” Retry Option -- put try/catch in a loop int tries = 0; public void foo () throws FileNotFoundException { FileInputStream in = new FileInputStream(“employee.dat”); while (tries < 3) { try { String s = getNameFromUser(); } FileInputStream in = new FileInputStream(“employee.dat”); } catch (FileNotFoundException e) { tries++; } } // end while loop Application Specific Exceptions • Components by “contract” i will do x if the parameters you send me conform to what i expect what if they don’t? Throw Application-Specific Exception boolean success = false; int tries = 0; while (tries < 3) { try { String s = getNameFromUser(); DataInputStream in = new DataInputStream (new FileInputStream(s)); success = true; } catch (FileNotFoundException e) { tries++; } } // end while if (!success) throw new UserIsJerkException (“user can’t supply a correct file name”); Application Specific Exceptions • Components by “contract” i will do x if the parameters you send me conform to what i expect throw application-specific exception