Exceptions Exceptions are used for dealing with things that can go wrong in a program. An exception usually signals an error but can also be used for dealing with exceptional events. Examples: User is required to enter an integer but types in a character; An age exceeds acceptable range; A command to open a file can't find the file. In Java we can throw an exception back to wherever its method was called from when we discover that something has gone wrong. OR we can catch the exception and try to correct the mistake. An exception in Java is an object that's created when an abnormal situation arises. The exception object has attributes that store information about the nature of the problem. An exception is always an object of some subclass of the standard class Throwable. Objec t derived from Throwable derived from derived from Error Exception do not catch these you should catch these Errors These are usually so serious that you can't do much about them e.g. running out of memory. You can catch them but there may be little you can do other than write out a message. Exceptions You can, and should, catch these since the compiler will check, except … Others … (Except these) RuntimeException Like …. NullPointerException Runtime Exceptions The exceptions represented by RuntimeException, which is itself a subclass of Exception, are differentiated from other subclasses in that the compiler will not check to see if your code tries to handle the exception. All other subclasses of Exception must be handled or thrown. If they are not, then your code will not compile. Page 1 of 6 06/15/16 Specifying the Exceptions a Method can throw We have seen this already with the BasicIO routines. If it is possible for a method to throw an exception that is not a subclass of Error or RuntimeException, then we should either handle the exception or state that we allow it to pass on: int getAge() throws Exception { } or int getAge() throws EOFException, FileNotFoundException { } This has a knock on effect; if another method calls this method, it too must either catch the exception or pass it on using throws. Handling exceptions To handle an exception where they occur, there are three kinds of code block that you can include: A try block encloses the code that may give rise to one or more exceptions A catch block encloses the code to handle the exception The code in a finally block is always executed before the try..catch block ends regardless as to whether an exception is raised or not. import java.util.*; public class TestException { public static void main (String[] args) { int ageOfPerson = 0; boolean successful = false; Scanner in = new Scanner(System.in); do { // The exception is expected to be thrown in the try try { System.out.print("Please enter your age "); ageOfPerson = in.nextInt(); successful = true; } // if an exception is thrown, it is caught here catch (InputMismatchException e) { System.out.println("That wasn't an integer " + e); in.nextLine(); } finally { System.out.println("I have just executed finally"); } } while (!successful); System.out.println("Ok success - you typed in " + ageOfPerson); } } Catching exceptions A catch block must immediately follow the try block that contains the code that may throw that particular exception. The catch block only handles the exception defined as a parameter. If your parameter is a base class then it will handle all exceptions. Page 2 of 6 06/15/16 Multiple catch blocks You can use multiple catch blocks after a try block, but the exception will be caught by the first catch block that processes this type of exception, or superclass of the exception. In other words you need to have the more specialised class exceptions handled first. Look at the following incorrect example: try { // try block code } catch (Exception e) { // general handling of exceptions } catch (ArithmeticException e) { // specialised handling of exception } Nothing will ever reach the second catch block as the first is more general. Defining your own exceptions There are two basic reasons for defining your own exception classes: You want to add information to a standard exception and then rethrow it. You may have error conditions in your code that requires a special exception class. There is a lot of overhead in handling exceptions so don't get carried away! User defined exceptions must be subclasses of Throwable; usually you use RuntimeException then the compiler checking for catch blocks will be suppressed. public class CounterException extends RuntimeException{ public CounterException() { // Do nothing. } // End default constructor public CounterException (String reason) { super (reason); } // End principal constructor } // End CounterException This is the minimum that must be provided. The String passed to the constructor will be added to the name of the class to form the message stored in the exception object. You can also add other constructors and attributes that can store additional information about a problem. Within the catch block you will have a handle on the exception and can thereby call the methods associated with an exception object. Throwing an exception We can throw an exception using the throw statement – why? Because we may wish to improve the standard behaviour (eg not stop when a word is typed for an int). This is how: throw new CounterException ("Attempt to count beyond limit."); Page 3 of 6 06/15/16 CounterException oops = new CounterException("Uh Oh"); throw oops; or Page 4 of 6 06/15/16 Summary of exceptions 1. Definition - The JVM throws exceptions when it meets exceptional (bad) things. Examples are NullPointerException, IOException, etc. 2. Compilation. If you haven’t said that your code might cause an exception the compiler will give you a message like this: Unreported exception java.io.FileNotFoundException must be caught or thrown. There are two solutions: a. Throwing the exception Just add something like this to the header of the method AND ANY METHOD THAT CALLS IT: public void load () throws IOException{ This indicates that you understand the dangers this method poses (you only need add throws FileNotFoundException but IOException is the base class for all the IO Exceptions. b. Catching the exception Put a try/catch block around the offending code try{ Scanner infile = new Scanner(new InputStreamReader ( new FileInputStream(fileName))); String n=infile.next(); String p=infile.next(); c=new Contact(n,p); infile.close(); } catch (IOException e) { System.out.println("no such file"); c=new Contact("unknown","unknown"); //do something sensible } Page 5 of 6 06/15/16 3. Run time. Sometimes your code fails because of a situation you haven’t guarded against. For instance: This shows you where the problem is. In this example the problem is that we never said c=new Contact() before we said c.readKeyboard() This problem should never be solved by try…. catching It is actually a logic error – make sure you have an object to call the method on!!! 4. Guarding against bad input: We have seen a few ways – and can also use exceptions: a. do…until and switch do{ this.printMenu(); String choice=in.next(); ch=choice.charAt(0); switch (ch) { case 'C': case 'c': … break; default: System.out.println("That is not a choice!"); } } while ((ch !='Q')&(ch !='q')); b. catch exceptions public void testException() { int input; try{ Scanner in =new Scanner(System.in); input=in.nextInt(); } catch (InputMismatchException e) { System.out.println("that is not an int"); input=0; } } How did I know that was the exception to catch? Either try it without and see what gets thrown or read the API for nextInt(). c. Make your own exceptions You can purposefully make your own exception and then throw it when something bad happens. This will throw the problem back to a place where you can handle it. Page 6 of 6 06/15/16