Java Exception Handling

Java Exception Handling – ClassCastException

Making our way through our detailed Java Exception Handling series, today we’ll be going over the ClassCastException. Any attempt to cast (i.e. convert) an object to another class for which the original class isn’t a inherited from will result in a ClassCastException.

In this article we’ll examine the ClassCastException by looking at where it sits in the grand Java Exception Hierarchy. We’ll also take a gander at some functional code samples that will illustrate how the ClassCastException is commonly thrown, and thus, how it can be avoided. Let’s get started!

The Technical Rundown

All Java errors implement the java.lang.Throwable interface, or are extended from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

To see how a ClassCastException is typically thrown we’ll be extending a Book class with a few inherited classes, namely PaperbackBook and DigitalBook. For this simple example, we need a simple class hierarchy, so our paperback and digital versions will each specify their own respective enum PublicationType value upon instantiation, differentiating each publication type from the others.

Note: To save space, we won’t go over the full Book class code here, but feel free to scroll up at the full code sample to have a look at it.

Instead, we’ll start with the aforementioned PublicationType enum:

Now, both the DigitalBook and PaperbackBook extend the Book class and, after passing all the standard parameters to the super (i.e. Book) constructor, they each set their publicationType property to the respective value:

As you may be aware, by extending Book these classes can use most of the functionality and methods that the base Book class provides, while also extending it with their own functionality. Consequently, an instance of the DigitalBook class or the PaperbackBook class can also be considered an instance of the Book class, since they are inherited children. However, the reverse cannot be said, because a Book instance is not necessarily also an instance of DigitalBook or PaperbackBook.

This can lead to some troubles when trying to perform explicit casts from one class type to another. For example, here we have a simple castToDigitalBook(Object source) method, which does just as the name suggests:

To test this out, we’ll start by instantiating a new DigitalBook and a new PaperbackBook:

There’s nothing unexpected going on here, so this code outputs both books to the log, confirming they’re each their respective subclass types:

However, now let’s try taking our paperbackBook instance and casting it to a DigitalBook instance:

This results in an immediate ClassCastException, which indicates that we cannot cast a PaperbackBook to DigitalBook:

As previously mentioned, this is because the source class (PaperbackBook) is not a direct descendant of the target class (DigitalBook). If it were, such a cast operation would work fine, which we can see by defining and calling the castToBook(Object source) method:

It’s important and interesting to note that, even though we explicitly cast PaperbackBook to a Book, the resulting object still remains a PaperbackBook, because it’s the most specific type of object that can be inferred from this cast command. In other words: There’s no reason to cast upward on the chain of inheritance, so it keeps the most extended option it can.

The Airbrake-Java library provides real-time error monitoring and automatic exception reporting for all your Java-based projects. Tight integration with Airbrake’s state of the art web dashboard ensures that Airbrake-Java gives you round-the-clock status updates on your application’s health and error rates. Airbrake-Java easily integrates with all the latest Java frameworks and platforms like Spring, Maven, log4j, Struts, Kotlin, Grails, Groovy, and many more. Plus, Airbrake-Java allows you to easily customize exception parameters and gives you full, configurable filter capabilities so you only gather the errors that matter most.

Check out all the amazing features Airbrake-Java has to offer and see for yourself why so many of the world’s best engineering teams are using Airbrake to revolutionize their exception handling practices!