An exception is an event that occurs during the execution of a
program that disrupts the normal flow of instructions.
Examples: hardware errors, array index out-of-bounds, divide by
zero, none existent file, ...
When such an error occurs Java throws an exception
Example: ExceptionArray.java
The array index is not checked, and if out of bound an
ArrayIndexOutOfBoundsException is thrown.
The java program then looks for an
exception handler.
The exception handler chosen is said to catch the exception
There are two types of exceptions:
Runtime exceptions: It is not necessary to provide
an exception handler for these - if they are not caught then
java dies.
Checked exceptions: It is necessary to provide an
exception handler for these - if none if provided then
javac reports an error.
When an exception occurs Java looks for a handler.
If it's a runtime exception and there is no handler, the
exception is passed to the calling method.
If it's a checked exception then there has to be a handler,
or code that explicitly passes the exception to the calling
method (see next point).
This process continues up to the main method, and out to the
java interpreter that prints an error message.
As well as exceptions caused by system errors, a program can throw
its own exceptions "on purpose", which is useful for dealing with
logical error situations.
Exceptions are objects!
Catching exceptions
Parts of code that may throw an exception can be (must be, for
checked exceptions) placed inside a try block, and
associated with each try block there must be one or more
catch blocks, or a finally block, or both.
The finally block is always executed.
If no error is thrown it is executed after the try block,
and if an error is caught it is executed after the catch
block.
It is executed even if there is a return statement.
Rather than catching an exception in the current method, the
exception can be thrown up to the calling code.
It always is good style, and necessary for checked exceptions, to
specify the exceptions that a method may throw up, using a
throws clause in the method header.
It is the reponsibility of the calling code to catch the exception
or throw it up again
Alternatively, a single catch block can catch more than
one type of exception.
This is achieved by specifying a generic exception type
(this will make more sense after we've studied inheritance),
at the expense of imprecise error messaging.
It is not necessary to catch and handle runtime exceptions, e.g.,
ArrayIndexOutOfBoundsException and
NegativeArraySizeException
If a non-handled runtime exception occurs, java reports
the exception and dies.
Checked exceptions, e.g., IOException, must be handled.
If a program uses a method that may throw a checked exception,
javac will report an error if the method does not handle
or hand up the exception.
Where does it all end .. the main method can hand up
checked exceptions, in which case java deals with it.
Simply add the throws clause to the main
method, e.g.,
public static void main(String[] args) throws IOException {
...
}