Java Exceptions

An exception object is always an instance of a class derived from Throwable, Throwable is splited into two branches: Error and Exception.

There are two kinds of excepton: unckecked exceptions and checked exceptions. Exceptions of type RuntimeException, Error, or subclasses of these types are unchecked exceptions and can be thrown anywhere without being declared, but it can be caught, like RuntimeException. Checked exceptions must be declared in a throws clause.

Exception types are not allowed to be generic types.

Static initializers and static initialization block cannot throw exceptions, either directly or by invoking a method that throws an exception. non-static initializers and non-static initialization blocks are considered to be part of the constructor, and so they are allowed to throw checked exceptions only if all the constructors declare those checked exceptions.

The constructors of subclass can throw new exceptions except those thrown by the constructors of the baseclass.

The throws clause of the overriding method must be compatible with the throws clause of the inherited method. It is ok to throw more specific exceptions, or not to throw any exceptions in the subclass method. If the superclass method throws no checked exception at all, neither can the subclass.

If a method declaration is multiply inherited, that is, it exists in more than one inherited interface, or in both an inherited interface and a superclass, then the throws clause of that method must satisfy all the inherited throws clauses, that means, a single implementation of a method can honor all the inhertited contracts.

try{
  //code that might throw exceptions
}
catch(FileNotFoundException | UnknownHostException e)
{
  System.out.println(e.getMessage());
}
finally
{}

Rethrowing and Chaining Exceptions

try {
  //access the database
}
catch(SQLException e)
{
  Throwable se = new ServletException("Database error");
  //when it is caught, the original exception e can be retrieved by getCause()
  se.initCause(e);
  throw se; 
}

You can catch the checked exception and wrap it into a runtime exception.

//it is ok, because compiler can track the fact the exeption is actually IOException
public void show() throws IOException { 
  try{
    throw new IOException();
  }
  catch(Exception e) {
    throw e; //
  }
}

It is a compile error for a catch clause to catch a checked exception type(like IOException) if the corresponding try clause cannot throw an exception of some subtype of the checked exception type(IOException). However, catch clause that catch Exception or Throwable are legal regardless of the contents of the corresponding try clause.

A finally clause can yield unexpected results when it contains return statements.

public static int f(int n) 
{
  try{
    int r = n * n;
    return r;
  } 
  finally {
    if(n==2) return 0; // at last, it returns 0 instead of 4 for f(2)
  }
}

Never exit a finally block with a return, break, continue, or throw, and never allow a checked exception to propagate out of a finally block.

Usually, we shoud use try{}finally{} block to read(write) from(to) a file, and put close method into finally block so that the file can be closed when exceptions happen, but if the close method throws an exception subsequently, how to hanle it?

To cope with the situation when the try block throws an exception and the close method in finally block also throws an exception, the try-with-resourcds statement rethrows the original exception and suppresses the exception thrown by close method(getSuppressed method yields an array of the suppressed exceptions from close method).

The AutoCloseable interface has a single method void close() throws Exception. For a resource belongs to a class that implements the AutoCloseable interface, you can use Try-with-Resources statement, then when the try block exits, the res.close() is called automatically.

try(Scanner in = new Scanner(new FileInputStream("file.txt")), 
  PrintWriter out = new PrintWriter("out.txt")) //multiple resources
{
  while(in.hasNext())
    out.println(in.next().toUpperCase());
}

java.lang.Throwable

java.lang.StackTraceElement

Last Updated 2015-11-14 Sat 20:50.

Created by Howard Hou with Emacs 24.5.1 (Org mode 8.2.10)