“Sneaky Throws” in Java

I just announced the new Spring 5 modules in REST With Spring:

1. Overview

In Java, the sneaky throw concept allows us to throw any checked exception without defining it explicitly in the method signature. This allows the omission of the throws declaration, effectively imitating the characteristics of a runtime exception.

In this article, we’ll see how this is done in practice, by looking at some code examples.

2. About Sneaky Throws

Checked exceptions are part of Java, not the JVM. In the bytecode, we can throw any exception from anywhere, without restrictions.

Java 8 brought a new type inference rule that states that a throws T is inferred as RuntimeException whenever allowed. This gives the ability to implement sneaky throws without the helper method.

A problem with sneaky throws is that you probably want to catch the exceptions eventually, but the Java compiler doesn’t allow you to catch sneakily thrown checked exceptions using exception handler for their particular exception type.

3. Sneaky Throws in Action

As we already mentioned, the compiler and the Jave Runtime can see different things:

The compiler sees the signature with the throws T inferred to a RuntimeException type,so it allows the unchecked exception to propagate. The Java Runtime doesn’t see any type in the throws as all throws are the same a simple throw e.

It’s possible to throw a checked exception using bytecode manipulation, or Thread.stop(Throwable), but it’s messy and not recommended.

4. Using Lombok Annotations

The @SneakyThrows annotation from Lombok allows you to throw checked exceptions without using the throws declaration. This comes in handy when you need to raise an exception from a method within very restrictive interfaces like Runnable.

Say we throw an exception from within a Runnable; it will only be passed to the Thread’s unhandled exception handler.

This code will throw the Exception instance, so there is no need for you to wrap it in a RuntimeException:

I just announced the new Spring 5 modules in REST With Spring:

I agree with the fact that checked exceptions can (and generally do) pollute the code with unnecessary try/catch blocks. Though I also do not like sneaky throws since you lose the context where the exception was sneakily thrown, which makes it almost impossible to pinpoint exceptions by looking at the stack trace logs. My personal approach on sanitizing methods throwing checked exceptions is to wrap them in a RuntimeException in the first place they occur. This way you can still keep your code clean (together with your peace of mind) and track down stack traces in the logs. What about… Read more »