Reputation: 837
I have a method getInstanceOfCause() that accepts an exception class and a Throwable, iterates through the cause of the Throwable and it's causes and returns the instance of the cause that matches the class passed as the first parameter. It looks like this:
public class ExceptionUtil {
public static <T> T getInstanceOfCause(Class<? extends Throwable> expected, Throwable exc) {
return (expected.isInstance(exc)) ? (T) exc : getInstanceOfCause(expected, exc.getCause());
}
}
Let's assume that the expected type is indeed in the "cause-chain" and the call won't cause a NPE. I am able to use it so:
MyException myException = ExceptionUtil.<MyException>getInstanceOfCause(MyException.class, exception);
This is awkward as I have to specify the type twice. Is there any way to rewrite the method signature so that I can use it like below, while still ensuring at compile time that the type is a subclass of Throwable?
MyException myException = ExceptionUtil.getInstanceOfCause(MyException.class, exception);
or
MyException myException = ExceptionUtil.<MyException>getInstanceOfCause(exception);
Upvotes: 1
Views: 31
Reputation: 271040
Note that T
can be inferred from your current method signature. One problem is that you can call it like this:
Foo foo = ExceptionUtil.getInstanceOfCause(MyException.class, exception);
which makes no sense.
I suppose you want to guarantee that the return value type and the type of class for the first parameter are the same?
You can make use of the generic parameter T
:
public static <T extends Throwable> T getInstanceOfCause(Class<T> expected, Throwable exc) {
return (expected.isInstance(exc)) ? (T) exc : getInstanceOfCause(expected, exc.getCause());
}
Note how I constrained T
to Throwable
, and used it in both Class<T> expected
and the return value type. This guarantees that the return value type is the same as the type of the class passed in.
Upvotes: 1