Ogen
Ogen

Reputation: 6709

Java generics with exceptions producing compile time errors

I have these two methods:

private static <T extends Throwable> void methodWithExceptionGeneric(final T t) throws T {
    throw t;
}

private static void methodWithExceptionNonGeneric(final Throwable t) throws Throwable {
    throw t;
}

When I call these methods like so:

methodWithExceptionGeneric(new IllegalArgumentException());
methodWithExceptionNonGeneric(new IllegalArgumentException()); // compile time error

I get a compile time error in the non generic method saying that I have an unhandled exception in my main method and I need to either declare a throws statement or catch the exception.

My question is: why is it only complaining about the non generic method? In my mind, the generic method is also throwing an exception so shouldn't that have to be handled too?

Upvotes: 0

Views: 978

Answers (1)

user4668606
user4668606

Reputation:

The reason is pretty simple:
IllegalArgumentException is a RuntimeException, which means it's an unchecked exception. You can catch it, but you don't have to. Since the generic method only throws IllegalArgumentException by it's specification, the compiler won't complain (unchecked exception).

The method without generics on the other hand is specified to throw any Throwable, which means it can also throw unchecked exceptions (and errors), which need to be handled.

This gets easy to see once you try to understand what happens with the generic method:

methodWithExceptionGeneric(new IllegalArgumentException());

is equivalent to

methodWithExceptionGeneric<IllegalArgumentException>(new IllegalArgumentException());

When we take a look at the definition

private static <T extends Throwable> void methodWithExceptionGeneric(final T t) throws T ...

turns into

private static <IllegalArgumentException> void methodWithExceptionGeneric(IllegalArgumentException) throws IllegalArgumentException ...

So methodWithExceptionGeneric(new IllegalArgumentException()); can only throw a IllegalArgumentException or any other unchecked Exception per definition. The non-generic method on the other hand can throw any Exception, be it checked or unchecked and thus must be called from within try-catch-block handling anything the method throws.

Upvotes: 2

Related Questions