Java Exceptions Definitive Guide

Java Exceptions is a language tool to react to exceptional cases (errors) in the runtime.

In other words, if something went wrong you can throw or catch an exception.

Let’s take a look at exception hierarchy in Java:

java exception hierarchy

In the top is  Throwable.

It’s a superclass for each exception and error in Java.

It contains main 3 things:

  1. Message – specific details, e.g.  FileNotFoundException contains the name of the file that can’t be found.
  2. Stacktrace – represents an array of stack elements with a name of the class and line number, so developers can easily understand who has thrown an exception.
  3. Cause – one throwable can be wrapped in another one, so this is a reference to a throwable that caused this throwable to get thrown.

The main subclasses are Exception, RuntimeException, and Error.

I’ll explain what are exception used for, best practices and frequently asked interview questions.

Java Exception Tutorial

There are 2 types of exceptions in Java: checked and unchecked.

Raising and handling both types of exceptions is more or less the same.

Let’s have a deeper look.

Checked Exceptions

Any subclass of Exception except RuntimeException is a checked exception.

That means you should declare it in method or constructor throws clause and you should handle it outside.

The most common checked exception list:

  • subclasses of IOException  ( FileNotFoundException, EOFException, ObjectStreamException)
  • exceptions related to concurrency ( InterruptedException, IllegalThreadStateException)
  • subclasses of  SQLException
  • text processing related exceptions like  ParseException

For example, we have a class User:

And we want to throw a checked exception if user not found by id.

Exception contains userId and builds a specific message:

And our service layer:

As you can see I had to declare  UserNotFoundException in the method signature.

Unchecked Exceptions

Any subclass of  RuntimeException or of Error is an unchecked exception.

Let’s take a deeper look at both of them.

Runtime Exception

If you take a look at Java exception hierarchy RuntimeException is a subclass of the  Exception class.

It’s not a usual subclass.

RuntimeException and all its subclasses are unchecked exceptions.

That means you should not declare it in method or constructor throws clause.

The most common unchecked exception list:

  • The most popular is  NullPointerException
  • IllegalArgumentExceptionIllegalStateException and its subclasses.
  • Collections and arrays related exceptions ( ArrayIndexOutOfBoundsException, IndexOutOfBoundsExceptionConcurrentModificationException)
  • Exceptions related to class casting like  ClassCastException

Let’s refactor our UserNotFoundException and UserService to the unchecked exception.

We should make our self-made exception a subclass of RuntimeException.

And remove  throws UserNotFoundException from service:

Looks a little bit cleaner, but if you want to force Java exception handling outside than you should use checked exceptions.

Error

Java error is a critical application problem.

You should not try to catch and handle it.

It’s no sense.

You shouldn’t declare Java errors in method or constructor throws clause as well.

That’s why errors relate to unchecked Java exceptions.

Common errors list:

  • Errors that are subclasses of  VirtualMachineError ( OutOfMemoryError, StackOverflowError, InternalError)
  • Errors related to class definition and reflection, that are subclasses of  LinkageError ( IllegalAccessError, NoClassDefFoundError, NoSuchMethodError, UnsupportedClassVersionError)

If you see error in logs that means you have to check carefully your code.

Sometimes you need to use special tools like profilers to find a problem.

How To Handle Exceptions

Let’s create a real-life situation.

A user can add a comment, but before storing new comment to the database we have to be sure that user exists.

The comment looks like this:

There 2 options how to handle exceptions:

  • Propagate exception to the next level
  • Catch exception in catch block

Let’s take a deeper look at comment service examples.

How To Propagate Exception

Propagate an exception means you don’t want to handle such exception on the current layer and someone else should handle it for you on the upper level.

Example:

As you can see I’ve added  throws UserNotFoundException to add method signature.

In case of unchecked exceptions, you shouldn’t add it.

How To Catch Exception

Java exception handling mechanism provides a try-catch-finally tool.

Example:

You’re executing your code inside of try block.

If the exception occurs inside of try block you’ll catch it in the catch block.

At the end finally block will be executed. Usually, you can close resources there.

Example:

As you can see if  UserNotFoundException occurs inside of  userService.findOne(userId) we can catch it and handle.

In our case I wrote a message to log and return false, that means the comment is not added.

Java Exception Handling Best Practises

I’ll write 5 the most important things that you should or should not do when you’re working with Java exceptions.

Throw Specific Exceptions

Java allows you to say: “Hey, my method throws some exception!”.

Sounds very generic.

The user doesn’t understand what exception is it and how he should handle it.

It’s a bad practice.

It’s better to let a user know what specific Java exceptions method can throw.

For example, your method needs to read a file and parse a text to say “hello”.

So you have 2 checked exceptions to declare.

Catch Specific Exceptions

More or less the same as a first rule.

You should catch specific exceptions instead of a generic exception.

For example, it’s better to write like this:

Instead of handling all Java exceptions in single catch block:

Don’t Throw Or Catch Throwable

It’s a bad idea to make your own exception subclass of  Throwable.

It’s bad practice to throw  new Throwable() or  catch (Throwable e) as well.

As far as you know  Error is a subclass of  Throwable.

And I mentioned above that you should not handle Java errors.

So if you will try to catch Throwable it’s possible that you’ll catch an Error that shouldn’t be handled.

Don’t Ignore Exceptions

You shouldn’t keep catch block empty.

You should log a message that exceptions occurred at least.

Something could happen and you will never know about it.

Write Informative Exception Messages

Add as more information there as you can.

It’s really easier to understand what exactly went wrong.

Don’t care if a message will be large.

This data can help you to fix bugs faster.

Interview Questions

I’ve prepared the most popular interview questions about Java exceptions.

You should definitely know answers before an interview.

What Is Java Exception Hierarchy?

You should know that Throwable is the main class.

Exception and Error extend Throwable.

RuntimeException extends Exception.

Take a look at exception hierarchy image at the beginning of the article.

You should know few specific examples of Exception, RuntimeException and Error as well.

What Types Of Exceptions Do You Know? When To Use Checked and Unchecked Exceptions?

There are 2 types of exceptions in Java: checked and unchecked.

You should use checked exception when you want to force the user to handle an exceptional situation.

It should be used for expected exceptions.

Unchecked exceptions are used for everything else.

But on my opinion checked exceptions make code ugly a little bit.

Some popular Java frameworks (Spring or Hibernate) or even another languages don’t use checked exceptions at all.

So I would say it depends on project rules and developer preferences.

Is Error Checked or Unchecked Exception?

You shouldn’t add error to method or constructor throws cause, that’s why an error is an unchecked exception.

Does Finally Block Executed If  You Will Throw an Exception In Catch Block?

Let’s imagine you caught an exception and program raised a new exception during exception handling.

Will finally block be executed?

Example:

The answer is yes, finally block will be executed anyway.

Output:

Can You Rethrow an Exception?

Yes, Throwable has a cause field, so you can specify an exception that was a reason of a current one.

Example:

We wrapped 1st exception (NPE) into  IllegalArgumentException and specified an exception message.

Is Throwable Interface Or Class

Throwable sound like an interface, it’s true.

But in fact, it’s a class.

James Gosling said:

The reason that the Throwable and the rest of those guys are not interfaces is because we decided, or I decided fairly early on.

I decided that I wanted to have some state associated with every exception that gets thrown.

And you can’t do that with interfaces; you can only do that with classes.

The state that’s there is basically standard. There’s a message, there’s a snapshot, stuff like that — that’s always there. and also, if you make Throwable an interface the temptation is to assign, to make any old object be a Throwable thing.

It feels stylistically that throwing general objects is probably a bad idea, that the things you want to throw really ought to be things that are intended to be exceptions that really capture the nature of the exception and what went on.

They’re not just general data structures.

You can check exceptions related questions in my Java interview questions collection post, some updates should appear time to time.

That’s it, ask your questions in comments.

Scroll Up