- A Concurrent Affair - https://www.concurrentaffair.org -

Generic Class May Not Extend Throwable

Another bit of Java trivia I just learned: A generic class may not implement Throwable. Interesting, huh? I guess Throwable and exceptions have a special meaning in Java and representation in the JVM, so there are probably some limitations, but I still find this irritating.

I was trying to write a wrapper exception that extended RuntimeException for the purpose of moving a checked exception out of a method that does not have a throws clause for that checked exception in a controlled fashion. This is what I tried:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class WrappedException<T extends Throwable>
    extends RuntimeException [1] {
    private T _wrapped;
    public WrappedException(String [2] message, T cause) {
        super(message, cause);
        _wrapped = cause;
    }
    public WrappedException(T cause) {
        super(cause);
        _wrapped = cause;
    }
    public T wrapped() { return _wrapped; }
}

It would have allowed me to do the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public someMethod() { // no throws clause
    try {
    ...
    }
    catch(IOException [3] e) { // checked exception
        throw new WrappedException<IOException>(e);
    }
}

public otherMethod() throws IOException [3] {
    try {
        someMethod();
    }
    catch(WrappedException<IOException> we) {
        throw we.wrapped();
    }
}

But I guess it all makes sense… It’s erasure at work. If you look at the catch clause, you just know this can’t work in Java: How will the JVM be able to distinguish a WrappedException<IOException> from a WrappedException<ClassNotFoundException>? It just can’t, with everything erased.

[4] [5]Share [6]