In the other hand, an Error is thrown by the Java system to notify about a non-recoverable error. Therefore, when an exception can be thrown and caught by your code, it is not a good practice to throw or catch an Error.
Exceptions
Any class which is a subtype of "Throwable" can be thrown and caught. Please see below the exception hierarchy:
A checked exception has to extend the class "Exception" (see the exception hierarchy above). It is designed to be either caught or declared in the method signature (ducking) if propagated.
An example of a method which throws checked exceptions:
// This method throws 2 types of checked exception
public String getUrl(String url)
throws UrlFormatException, UrlNotAvailableException {
if(!checkUrlFormat(url)){
throw new UrlFormatException(url);
}
if(!callUrl(url)){
throw new UrlNotAvailableException(url);
}
...
}
An unchecked exception has to extend the class "RuntimeException". It is designed to be silently propagated. Therefore, a method which throws an unchecked exception, does not have to declare it in its signature (ducking).
I would recommend using unchecked exceptions to avoid forcing the depending codes to either catch them or declare these exceptions in their signatures. Indeed, it is not always required to catch an exception as this depends in the responsibility of each method. Using unchecked exception simplifies codes by eliminating unnecessary try-catch blocks and method declarations with aggregated exception declarations.
Rod Johnson (founder of the Spring Framework), and Joshua Bloch (Effective Java, item 41: Avoid unnecessary use of checked exceptions) recommend using unchecked exceptions as a default approach.
Catching exceptions
try{
userService.cacheUsers();
}catch(UserServiceException ex){
// do something
}catch(Exception ex){
// do something
} finally {
// do something
}
Note that since Java 7, you can catch many exceptions in a single "catch" statement:
try{
userService.cacheUsers();
}catch(UserServiceException|Exception ex){
// do something
} finally {
// do something
}
This is useful when you want to execute a similar logic for many type of exceptions.
Important rules about the try/catch/finally statements:
- when catching many exceptions, the most specific exceptions must always be placed above those for more general exception (like "Exception" class). If you do opposite, it means that a specific exception will never be caught, in this case the program will not compile.
- whether an exception is caught or not, a "finally" statement is always executed after a try block. Note that even if there is a "return" statement or an exception is thrown from the try or catch block, the finally block is executed before the execution of "return" or "exception".
An example of how finally behaves when an exception is thrown:
try{
System.out.println("Throw Exception");
// 'finally' will still be executed just before 'RuntimeException' is executed
throw new RuntimeException();
}finally{
System.out.println("finally");
}
This code produces:
Throw Exception
finally
Exception in thread "main" java.lang.RuntimeException at Test.main(Test.java:6)
Errors
An "Error" class is a subtype of "Throwable". Therefore any class which subclass "Error" can be thrown and caught.
Error are thrown by the JVM. You can catch them, however it will usually be useless since an error is likely to stop the execution of your program.
Description of common exceptions and errors:
Exception
|
Description
|
Typically thrown
|
ArrayIndexOutOfBoundsException
|
Thrown when atempting to access an array with an invalid index value, which is either negative or beyond the length of the array.
|
By the JMV
|
ClassCastException
|
Thrown when attempting to cast a reference variable to a type that fails the IS-A test.
|
By the JMV
|
IllegalArgumentException
|
Thrown when a method receives an argument formatted differently than the method expects.
|
Programmatically
|
IllegalStateException
|
Thrown when state of the environment doesn't match the operation being attempted.
eg., using a "FileWriter" that's been closed
|
Programmatically
|
NullPointerException
|
Thrown when attempting to access an object with a reference variable whose current value is null.
|
By the JMV
|
NumberFormatException
|
Thrown when a method that converts String to a number receives a String that it cannot convert.
|
Programmatically
|
AssertionError
|
Thrown when a statement's boolean test returns false.
|
Programmatically
|
ExceptionInInitializerError
|
Thrown when attempting to initialize a static variable or an initialization block.
|
By the JMV
|
StackOverflowError
|
Thrown when a method recurses too deply in the stack with overflowing it.
|
By the JMV
|
NoClassDefFoundError
|
Thrown when the JVM can't find a class it needs, because of a command-line error, a classpath issue, or a missing .class file.
|
By the JMV
|

