Unit 4.1 - Exceptions in Java
Unit 4.1 - Exceptions in Java
What is an exception?
● An exception is an error condition that changes the
normal flow of control in a program
● Exceptions in Java separates error handling from main
business logic
● Based on ideas developed in Ada, Eiffel and C++
● Java has a uniform approach for handling all
synchronous errors
∙ From very unusual (e.g. out of memory)
∙ To more common ones your program should check itself (e.g.
index out of bounds)
∙ From Java run-time system errors (e.g., divide by zero)
∙ To errors that programmers detect and raise deliberately
Throwing and catching
● Error
– “unchecked”, thus need not be in ‘throws’ clause
– Serious system problems (e.g. ThreadDeath, OutOfMemoryError)
– It’s very unlikely that the program will be able to recover, so
generally you should NOT catch these.
● RuntimeException
– “unchecked”, thus need not be in ‘throws’ clause
– Also can occur almost anywhere, e.g. ArithmeticException,
NullPointerException, IndexOutOfBoundsException
– Try to prevent them from happening in the first place!
● System will print stop program and print a trace
Java is strict
● Unlike C++, is quite strict about catching exceptions
● If it is a checked exception
– (all except Error, RuntimeException and their subclasses),
– Java compiler forces the caller must either catch it
– or explicitly re-throw it with an exception specification.
● Why is this a good idea?
● By enforcing exception specifications from top to bottom,
Java guarantees exception correctness at compile time.
● Here’s a method that ducks out of catching an exception by
explicitly re-throwing it:
void f() throws tooBig, tooSmall, divZero {
– The caller of this method now must either catch these
exceptions or rethrow them in its specification.
Catching an exception
try { // statement that could throw an exception
}
catch (<exception type> e) {
// statements that handle the exception
}
catch (<exception type> e) { //e higher in hierarchy
// statements that handle the exception
}
finally {
// release resources
}
//other statements
● At most one catch block executes
● finally block always executes once, whether there’s an error or
not
Execution of try catch blocks
● For normal execution:
– try block executes, then finally block executes, then other statements execute
● When an error is caught and the catch block throws an exception or returns:
– try block is interrupted
– catch block executes (until throw or return statement)
– finally block executes
● When error is caught and catch block doesn’t throw an exception or return:
– try block is interrupted
– catch block executes
– finally block executes
– other statements after catch executes
● When an error occurs that is not caught:
– try block is interrupted
– finally block executes
Catch processing
● When an exception occurs, the nested try/catch statements are
searched for a catch parameter matching the exception class
● A parameter is said to match the exception if it:
– is the same class as the exception; or
– is a superclass of the exception; or
– if the parameter is an interface, the exception class implements the
interface.
● The first try/catch statement that has a parameter that matches
the exception has its catch statement executed.
● After the catch statement executes, execution resumes with the
finally statement, then the statements after the try/catch
statement.
Catch processing example
print("now");
try
{ print("is ");
throw new MyException();
print("a ");
}
catch(MyException e) { print("the "); }
print("time\n");
● Prints "now is the time".
● Note that exceptions don't have to be used only for error handling
● Would it be a good idea to exceptions for non-error processing?
● But any other use is likely to result in code that's hard to understand.
Declaring an exception type
● Inherit from an existing exception type.
● Provide a default constructor
● and a constructor with one arg, type String.
● Both should call super(astring);
● Example: