730 likes | 746 Views
Chapter 15: Exception Handling. Tues. Nov. 25. Learning about Exceptions. An exception is an unexpected error or condition, such as You issue a command to read a file from a disk, but the file does not exist there You attempt to write data to a disk, but the disk is full or unformatted
E N D
Chapter 15: Exception Handling Tues. Nov. 25
Learning about Exceptions • An exception is an unexpected error or condition, such as • You issue a command to read a file from a disk, but the file does not exist there • You attempt to write data to a disk, but the disk is full or unformatted • Your program asks for user input, but the user enters invalid data • The program attempts to divide a value by 0
Exception Handling… • These are the object-oriented methods to manage such errors • Java has two basic classes of errors: Error and Exception • Both of these classes descend from the Throwable class, as shown next
The Exception and Error Class Hierarchy • Object • Throwable • Exception • IOException • Runtime Exception • ArithmeticException • IndexOutOfBoundsException • ArrayIndexOutOfBoundsException • Others • Error • VirtualMachineError • OutofMemoryError • InternalError • Others…
Error Class • These are serious errors from which your program cannot recover • Such as, a misspelled class name or a class stored in the wrong folder • If the program cannot find the class, an Error condition occurs • If the program runs out of memory, an Error condition occurs
Exception class • These are less serious errors that represent unusual conditions that arise while the program is running and from which the program can recover • Examples include using an invalid array subscript or performing certain illegal arithmetic operations • Your program can determine the type of error by examining the code of the error returned by Java
Example of Fatal Error at Command Prompt C:\Java\Java xyz.java error: cannot read xyz.java 1 error C:\Java\>_ • In this case there is no program code you could write that could fix or prevent the error message
Exception messages • When the program generates an exception message, it produces a different type of message • An exception message is one that could have been prevented by writing specific methods in the program • Consider the following program…
public class MathMistake { public static void main(String[] args) { int num = 13, denom = 0, result; result = num / denom; } }
Exception Message generated by program above C:\Java\java MathMistake Exception in thread “main” java.lang.ArithmeticException: / by zero at MathMistake.main<MathMistake.java:6> C:\Java>_ • The Exception is a java.lang.ArithmeticException which is one of many subclasses of Exception • You are told the type of error as well as the line number of the error
Your Program’s Response • You can simply let the program terminate • The termination is abrupt and unforgiving • This might annoy the user • Or the termination could be disastrous such as in an air traffic control situation
Understanding the Limitations of Traditional Error Handling • Consider the following arithmetic (division by 0) error and its various traditional ways of handling the error
Using System.exit(1); public class MathMistake { public static void main(String[] args) { int num = 13, denom = 0, result; if(denom == 0) System.exit(1); result = num / denom; } }
Using System.exit(1); • When you use System.exit(), the current application ends and control returns to the operating system • The convention is to return a value of 1 if an error is causing the termination; otherwise, a value of 0 is returnedunder normal termination • Using System.exit() circumvents displaying the error message shown above because the program ends before the the division by zero occurs
User-generated exception handling • When you write code to detect exceptions, you ‘try’ a procedure that might cause an error • A method that detects an exception ‘ throws an exception,’ and the block of code that processes the error ‘catches the exception.’ • Programs that can handle exceptions are said to be more fault tolerant and robust • Fault-tolerant apps are designed so that they continue to operate, possibly at a reduced level
Trying Code and Catching Exceptions • When you create a segment of code in which something might go wrong, you place the code in a try block, which is a block of code you attempt to execute while acknowledging that an exception might occur
A try block consists of the following elements: • The keyword catch • An opening parenthesis • An Exception type • A name for an instance of the Exception type • A closing parenthesis • An opening curly brace • The statements that take the action you want • A closing curly brace
General format for a method that contains a try…catch pair returnType methodName(optional arguments) { optional statements prior to code that is tried try { //statements that might generate an exception } catch(Exception someException) { // actions to take if exception occurs } // optional statements that occur after try }
try and catch—how they work • In the slide above, someException represents an object of the Exception class or any of its subclasses • If an exception occurs during the execution of the try block, the statements in the catch block execute • If no exception occurs within the try block, the catch block does not execute • Either way the statements following the catch block execute normally
Example of try and catch public class MathMistakeCaught { public static void main(String[] args) { int num = 13, denom = 0, result; try { result = num / denom; } catch(ArithmeticException mistake) { System.out.println("Attempt to divide by zero!"); } } }
Output from the above program • C:\Java>java MathMistakeCaught • Attempt to divide by zero! • C:\Java>
Error Outputs • If you want to send error messages to a different location from ‘normal’ you can use System.err instead of System.out
How to determine the type and source of the error • Lots of different types of errors could have occurred within the try block • You can have the system print the type of error with the following code
public class MathMistakeCaught2 { public static void main(String[] args) { int num = 13, denom = 0, result; try { result = num / denom; } catch(ArithmeticException mistake) { System.out.println(mistake.getMessage()); } } }
The above code… • Uses the getMessage() method to generate the message that ‘comes with’ the caught ArithmeticException argument to the catch block
The above code generates the following output C:\Java>java MathMistakeCaught2 / by zero C:\Java>_
Catch should do more than just print an error message… try { result = num / denom; } catch(ArithmeticException mistake) { result = num/1; System.out.println(mistake.getMessage()); }
Now, result… • Holds a valid value—either the code in the try block worked, or the code in the catch block assigned a valid value to result if the try block did not work
Notice in the above… • The catch blocks are written so that they look like methods
Throwing and Catching Multiple Exceptions • You can place as many statements as you need within a try block and you can catch as man Exceptions as you want • However, the first such Exception will cause the logic to leave the try block and to enter the catch block • Thus, the first error-generating statement throws an Exception • When a program contains multiple catch blocks, they are examined in sequence until a match is found for the type of Exception that occurred
Throwing and Catching Multiple Exceptions, Continued • Then, the matching catch block executes and each remaining catch block is bypassed • For example, consider the code below
Two mistakes and two catch blocks public class TwoMistakes { public static void main(String[] args) { int num[] = {4, 0, 0}; try { num[2] = num[0] / num[1]; num[2] = num[3] / num[0]; } catch(ArithmeticException e) { System.out.println("Arithmetic error"); } catch(IndexOutOfBoundsException e) { System.out.println("Out of bounds error"); } System.out.println("End of program"); } }
The above program produces the following output • C:\Java\java TwoMistakes • Arithmetic error • End of program • C:\Java>_ • Note that the second statement in the try block is never attempted and the second catch block is skipped
Out of bounds error program public class TwoMistakes2 { public static void main(String[] args) { int num[] = {4, 0, 0}; try { num[2] = num[0] / 10; num[2] = num[3] / num[0]; } catch(ArithmeticException e) { System.out.println("Arithmetic error"); } catch(IndexOutOfBoundsException e) { System.out.println("Out of bounds error"); } System.out.println("End of program"); } }
Out-of-bounds error • C:\Java\java TwoMistakes2 • Out of bounds error • End of program • C:\Java>_ • Again, the try block is abandoned, the first catch block is examined and found unsuitable because it does not catch an IndexOutOfBoundsException • The program proceeds to the second catch block
Using only one catch block for all exceptions • The following program uses only one catch block to catch both ArithmeticExceptions and IndexOutOfBounds exceptions • The above exceptions are both subclasses of Exception • Therefore, the catch blocks shown above can be replaced with a single generic catch block, as shown below
A single generic catch block public class TwoMistakes3 { public static void main(String[] args) { int num[] = {4, 0, 0}; try { num[2] = num[0] / num[1]; num[2] = num[3] / num[0]; } catch( Exception e) { System.out.println(e.getMessage()); } } }
The above generic catch block.. • Will catch all exceptions • When either an arithmetic exception or array index exception occurs, the thrown exception is ‘promoted’ to an Exception error in the catch block • Because an Exception is Throwable, you can use the Throwable class getMessage() method
Generic and Specific Catch blocks • If you place a generic catch block first and then specific catch blocks afterwards, the specific catch blocks will possess code that is unreachable because the generic catch block will catch all exceptions before they can be tested against specific catch blocks • Unreachable code statements are program statements that can never execute under any circumstances. • Try blocks should not throw more than four exception types
Using the finally Block • finally blocks follow catch blocks and are used to cleanup after try and catch blocks regardless of whether an exception occurred or not
Format of try/catch/finally Try { // statements of try } catch(Exception e) { // actions taken if exception was thrown } finally { // actions taken whether catch block executed or not }
Statements in the finally block do not execute when… • There is a System.exit(); statement in either the try block or the catch block • An unplanned Exception occurs • When an unplanned Exception occurs, the application is stopped and control is returned to the operating system where the Exception is handled—the program is abandoned
Pseudocode that tries reading a file try { // Open the file // Read the file // Place the file data in an array // Calculate an average from the data // Display the average } catch(IOException e) { // Issue an error message // System exit } finally { // if file is open, close it }
Understanding the Advantages of Exception Handling • The advantage of exception handling is that it enables you to create a fix-up for the exception and to permit the program to continue • It also simplifies exception handling overall
call methodA() If methodA() worked { call methodB() if methodB() worked { call methodC() if methodC() worked Everything is OK so print final result else Set errorCode to ‘C’ } else Set errorCodee to ‘B” } else Set errorCode to ‘A’ }
try { call methodA() and maybe throw an exception call methodB() and maybe throw an exception call methodC() and maybe throw an exception } Catch(methodA()’s error) { set errorCode to ‘A’ } Catch(methodB()’s error) { set errorCode to ‘B’ } Catch(methodC()’s error) { set errorCode to ‘C’ }
Advantages of second pseudocode • Logic is much simplier • Reusability of the method is much better • If a method throws an exception that will not be caught inside the method, you must use the keyword throws followed by an Exception type in the method header • Consider the following code…
Public class PriceList { private static final double[] price = {15.99,27.88,34.56,45.89}; public static void displayPrice(int item) throws IndexOutOfBoundsException { System.out.println(“The price is” + price[item]; } }
public class PriceListApplication1 { public static void main(String[] args) { int item = 4; try { PriceList.displayPrice(item); } catch(IndexOutOfBoundsException e) { System.out.println("Price is $0"); } } }
import javax.swing.*; public class PriceListApplication2 { public static void main(String[] args) { int item = 4; try { PriceList.displayPrice(item); } catch(IndexOutOfBoundsException e) { while(item < 0 || item > 3) { String answer = JOptionPane.showInputDialog(null, "Please reenter a value 0, 1, 2 or 3"); item = Integer.parseInt(answer); } PriceList.displayPrice(item); } System.exit(0); } }