Semyon Burov
Semyon Burov

Reputation: 1172

Generics type erasure and type cast

I want to travel down the exception causes until I find "the right one", but it looks like the type is being erased and the function returns the passed exception which results in ClassCastException in main. Here is my code:

public class Main {

public static void main(String[] args) {
    Throwable e0 = new CertPathValidatorException("0");
    Throwable e1 = new CertificateException(e0);
    Throwable e2 = new CertificateException(e1);
    Throwable e3 = new CertificateException(e2);

    CertPathValidatorException cpve = Main.<CertPathValidatorException>getCauseOf(e3);
}

@Nullable
private static <Ex extends Exception> Ex getCauseOf(final Throwable e) {
    Throwable cause = e;
    while (true) {
        try {
            return (Ex) cause;
        }
        catch (ClassCastException cce) {
            cause = cause.getCause();
        }
    }
}

}

Is there a way to keep this function generic, or should I abandon this idea?

Upvotes: 0

Views: 40

Answers (1)

amanin
amanin

Reputation: 4184

Using generics here is dangerous. Java resolves generic types at compile time. In your code, you would require a resolve at runtime. You can do so by passing a class as parameter to your function in addition.

private static <Ex extends Exception> Ex getCauseOf(final Class<Ex> typeResolve, final Throwable e) {
    Throwable cause = e;
    while (cause != null) {
        if (typeResolve.isInstance(cause)) return (Ex) cause; // or typeResolve.cast(cause);
        else cause = cause.getCause();
    }
    return null;
}

This way, you can modify the call as following:

CertPathValidatorException cpve = Main.getCauseOf(CertPathValidatorException.class, e3);

Upvotes: 2

Related Questions