5. Exceptions
Java uses a form of error-trapping called exception handling
Dealing with Errors
The Classification of Exceptions
In Java, an exception object is always an instance of a class derived from Throwable
You can create your own exception classes
The Error hierarchy describes internal errors and resource exhaustion inside the Java runtime system. You should not throw an object of this type
There is little you can do for such errors, beyond notifying the user and trying to terminate the program gracefully
When doing Java programming, you focus on the Exception hierarchy, exception that derive from RuntimeException and that do not
Exceptions that inherit from RuntimeException include - A bad cast, An out-of-bounds array access, A null pointer access
Exceptions that do not inherit from RuntimeException - Trying to read pat the EOF, Trying to open a malformed URL, etc
The rule - "if it is a RuntimeException, it was your fault"
The Java Language Specification calls any exception that derives from the class Error or the class RuntimeException an unchecked exception
All other exceptions are called checked exceptions
Throwable
-> Error
-> Exception
-> IOException
-> Runtime Exception
Advertising the Exceptions that a Method Throws
A Java method can throw an exception if it encounters a situation it cannot handle
public String readLine() throws IOException {}
public Image loadImage(String s) throws EOFException, MalformedURLException {}
The header indicates this method returns string, but it also has the capacity to go wrong in a special way - by throwing an IOException\
The runtime system will begin to search for an exception handler that knows how to deal with IOException object
If either of below two scenario occurs, you must tell the consumer of the method that there is the possibility of an exception
You can call method that throws a checked exception, for example any IO exception
You detect an error and throw a checked exception with the throw statement
You code should handle unchecked exceptions
In summary, a method must declare all the checked exceptions that it might throw
You could also catch all exceptions, and no throws specification is necessary
How to Throw an Exception
Find an appropriate exception class
Make an object of that class
Throw it
String readData(BufferedReader in) throws EOFException {
...
throw new EOFException();
}
Creating Exception Classes
Create your own exception class from Exception or its subclass
It is customary to give both a default constructor and a constructor that contains a detailed message
class FileFormatException extends IOException {
public FileFormatException() {}
public FileFormatException (String gripe) {super(gripe);}
}
String readData(BufferedReader in) throws FileFormatException {
...
throw new FileFormatException ();
}
Catching Exceptions
If any of the code inside the try block throws an exception of the class specified in the catch clause
The program skips the remainder of the code in the try block
The program executes the handler code inside the catch clause
If none of the catch clause matches the thrown exception, the method exits immediately
If none of the code inside the try block throws an exception, then the program skips the catch clause
As a general rule, you should catch those exceptions that you know how to handle
Propagate those you do not know how to handle
try
{
String line - reader.readLine();
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
}
catch (IOException e2)
{
e2.printStackTrace();
}
e.printStackTrace()
e.getMessage()
e.getClass().getName()
Rethrowing Exceptions
You may need to catch exception without addressing the root cause of it
Typical you do local cleanup but it can't fully resolve the problem so rethrow the exception
try
{
...
}
catch (MalformedURLException e)
{
localCleanup();
throw e;
}
The finally Clause
This is typically used to cleanup local resources both in normal flow and exception flow
Executed if the code throws no exception and code in finally clause
Executed if code throws exception, executes code in matching catch clause and code in finally clause
Executed if code throws exception, no matching catch clause, code in finally clause and then exception is thrown back to caller
You can use the finally clause without a catch clause
try
{
...
}
catch (IOException e)
{
...
}
finally
{
localCleanup();
}
Some Tips on Using Exceptions
Exception handling is not supposed to replace a simple test e.g. empty stack pop. Use for exceptional circumstances only
Do not micromanage exceptions around every statement, have bigger try block instead
Do not squelch exceptions. Handle exception and add trace logging
Propagating exceptions is not a sign of shame