Exceptions Ensuring program reliability
Jan 01, 2016
Exceptions
Ensuring program reliability
Program correctness
• The term program correctness refers to a program’s working as advertised; that is, it produces correct results for valid inputs
• A related concept is program reliability; this is a measure of how well a program performs under a variety of conditions (including invalid inputs)– A program can be correct, but not reliable– A program can be reliable, but not correct– Our goal is to produce programs with both these
qualities
Ensuring reliability
• We do our best to ensure program correctness through a rigorous testing and debugging process
• To ensure reliability, we must anticipate conditions that could cause problems, and try to deal with them before the problems occur
• In Java, we have exception handling, a powerful tool for ensuring program reliability
Catching Exceptions
• An exception represents an error condition that can occur during the normal course of program execution.
• When an exception occurs, or is thrown, the normal sequence of flow is terminated. The exception-handling routine is then executed; we say the thrown exception is caught.
Catching Exceptions
• We can increase our programs’ reliability and robustness if we catch the exceptions ourselves using error recovery routines we develop.
• One way to do this is to wrap the statements that may throw an exception with the try-catch control statement.
Catching Exceptions - example
inputStr = JOptionPane.showInputDialog(null, prompt);
try {
age = Integer.parseInt(inputStr); // code that might cause error
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, “” + inputStr + “ is invalid\n” + “Please enter digits only”);
}
Catching Exceptions
• A try-catch block is similar to a selection structure
• If no error occurs (in the example, if the user entered only digits), the catch block is ignored
• If there is an error, the catch block executes
Catching Exceptions
• Statements in the try block are executed in sequence.
• If more than one exception is possible, multiple catch blocks can be written
• When one of the statements throws an exception, control is passed to the matching catch block and statements inside the catch block are executed.
Two control flows of the try-catch statement with one catch block.
Catching Exceptions
• We must specify which exception we are catching in the catch block’s parameter list.
• In Java an exception is represented as an instance of the Throwable class or its subclasses.
• The Throwable class has two subclasses:– Error– Exception
Catching Exceptions
• The Error class represents serious problems that should not be caught by ordinary applications
• The Exception class represents error conditions that should be caught
Throwable class inheritance hierarchy – a sample
Propagating Exceptions
• When a method may throw an exception, either directly or indirectly, we call the method an exception thrower.
• Every exception thrower must be one of two types:– catcher.– propagator.
Propagating Exceptions
• An exception catcher is an exception thrower that includes a matching catch block for the thrown exception.
• An exception propagator does not contain a matching catch block.
• A method may be a catcher of one exception and a propagator of another.
Propagating Exceptions
• If a method is an exception propagator, we need to modify its header to declare the type of exceptions the method propagates.
• We use the reserved word throws for this declaration.void C( ) throws Exception {...}void D( ) throws Exception {...}
Propagating Exceptions
• Without the required throws Exception clause, the program will not compile.
• However, for the exception of the type called runtime exceptions, the throws clause is optional.
Throwing Exceptions
• An exception is thrown using the throw statement.
throw <a throwable object>
• where <a throwable object> is an instance of the Throwable class or its subclasses.
Throwing Exceptions
• If there is a block of code that must be executed regardless of whether an exception is thrown, we use the reserved word finally.
inputStr = JOptionPane.showInputDialog(null, “”);try{
number = Integer.parseInt(inputStr);if (num>100) {
throw new Exception(“Out of bound”);}
} catch (NumberFormatException e) { System.out.println(“Cannot convert to int”);
} catch (Exception e) { System.out.println(“Error: ” + e.getMessage());
} finally { System.out.println(“DONE”);
}
Throwing Exceptions
• When there are multiple catch blocks in a try-catch statement, they are checked in sequence.
• It is important to check more specialized exception classes before the more general exception classes.
• When an exception is thrown, its matching catch block is executed and the other catch blocks are ignored.
Catching Exceptions
• There are two methods of the Throwable class we can call to get information about the thrown exception:–getMessage–printStackTrace
2 possible outcomes of the try-catch statement with multiple catch blocks
Throwing Exceptions
• If none of the catch blocks matches the thrown exception, the system will search down the stack trace for a method with a matching catch block.
• If none is found, the system will handle the thrown exception.
Throwing Exceptions
• Even if there is a return statement inside the try block, the finally block is executed.
• When the return statement is encountered in the try block, statements in the finally block are executed before actually returning from the method.
2 possible outcomes of the try-catch statement with multiple catch blocks and the finally block
Propagating Exceptions
• Do not catch an exception that is thrown as a result of violating a condition set by the client programmer.
• Instead, propagate the exception back to the client programmer’s code and let him or her handle it.
Example// Class to input age: allows client programmers to specify the// lower and upper bounds of acceptable input values
import javax.swing.*;
class AgeInput {private static final String DEFAULT_MESSAGE = "Your age:";
private static final int DEFAULT_LOWER_BOUND = 0; private static final int DEFAULT_UPPER_BOUND = 99; private static final int DEFAULT_LOWER_BOUND = 0; private static final int DEFAULT_UPPER_BOUND = 99; private int lowerBound, upperBound;
private void setBounds(int low, int high) { lowerBound = low; upperBound = high; }
Example continuedpublic AgeInput ( ) throws IllegalArgumentException { setBounds(DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);}
public AgeInput (int low, int high) throws IllegalArgumentException { if (low > high) { throw new IllegalArgumentException("Low (" + low + ") was " +
"larger than high(" + high + ")"); } else { setBounds(low, high); }}
public int getAge() throws Exception { return getAge(DEFAULT_MESSAGE);}
public int getAge(String prompt)throws Exception { String inputStr; int age; while (true) { inputStr = JOptionPane.showInputDialog(null, prompt); try { age = Integer.parseInt(inputStr); if (age < lowerBound || age > upperBound) { throw new Exception("Input out of bound"); } return age; // input okay so return the value & exit } catch (NumberFormatException e) { JOptionPane.showMessageDialog(null, "'" + inputStr +
" is invalid\n“ + "Please enter digits only"); } // end catch block } // end while loop } // end method} // end class
Types of Exceptions
• There are two types of exceptions:– Checked.– Unchecked.
• A checked exception is an exception that is checked at compile time.
• All other exceptions are unchecked, or runtime, exceptions. As the name suggests, they are detected only at runtime.
Types of Exceptions
• If a method is a propagator of checked exceptions, the method must have the throws clause.
• When calling a method that can throw checked exceptions, use the try-catch statement and place the call in the try block, or modify the method header to include the appropriate throws clause.
• If a method is a propagator of runtime exceptions or errors, the throws clause is optional.
Calling a method that can throw an exception: two options
Calling method that throws a runtime exception – 3 options