IIUC, for checked exceptions Java lacks parametric polymorphism (generics).
Edit: Not sure why the downvote.
This works in Java today with proper pattern matching (I left out the complete name from the permit clause, it won’t compile as is):
sealed interface <T,E> Result permits Ok, Error {
record Ok(T val) implements Result<T,E> {}
record Error(E err) implements Result<T,E> {}
}(and no, I have no idea why you're being downvoted, please take my upvote)
class Exception1 extends Exception {}
class Exception2 extends Exception {}
interface ThrowingFunction {
void apply() throws Exception1, Exception2;
}
class Foo {
public void doFoo(ThrowingFunction f) throws T {
f.apply();
}
public static void main() throws Exception1, Exception2 {
new Foo().doFoo(() -> {
if (false) {
throw new Exception1();
}
if (false) {
throw new Exception2();
}
});
}
}}
However, if you pass them through a generic then they will be flattened into the closest common ancestor: class Exception1 extends Exception {}
class Exception2 extends Exception {}
interface ThrowingFunction<T extends Throwable> {
void apply() throws T;
}
class Foo {
public <T extends Throwable> void doFoo(ThrowingFunction<T> f) throws T {
f.apply();
}
// Fails to compile, because Exception is still unhandled
public static void main() throws Exception1, Exception2 {
new Foo().doFoo(() -> {
if (false) {
throw new Exception1();
}
if (false) {
throw new Exception2();
}
});
}
}Is it possible to provide a map method that re-throws whatever is thrown by its argument, without widening?