3 ms·
Java generics just aren't powerful enough to express that a higher order function's exceptions depend on its args, so pretty much everyone has given up on speci
by erik_seaberg 6y ago
Java generics just aren't powerful enough to express that a higher order function's exceptions depend on its args, so pretty much everyone has given up on specific checked exceptions.
- twic 6y agoYes, they are: @FunctionalInterface public interface ThrowingConsumer<T, E extends Throwable> { void accept(T value) throws E; } public static <T, E extends Throwable> void forEach(Collection<T> elements, ThrowingConsumer<T, E> consumer) throws E { for (T element : elements) { consumer.accept(element); } } There is a significant shortcoming, which is that you can't catch exceptions using the type parameter - this does not compile: public static <T, E extends Throwable> Optional<E> forEach(Collection<T> elements, ThrowingConsumer<T, E> consumer) { for (T element : elements) { try { consumer.accept(element); } catch (E e) { // <-- not allowed! return Optional.of(e); } } return Optional.empty(); } You can kludge your way around that in various ways, but none of them are pretty.
- erik_seaberg 6y agoYeah, that sort of works, though I’m not sure a function that throws two distinct exception could be compatible with a generic method that takes functions throwing three distinct exceptions (that may sound crazy but some java.security crypto stuff does it).
- Yeroc 6y agoLooking back on it now I think our revulsion to simply using "throws Exception" ought to be re-examined. In practice, while it's nice to know exactly what kinds of exceptions are being thrown it could be the emphasis on this actually holds us back. What's more important is whether an Exception could be thrown at all versus none.
- twic 6y agoYou can bind unused parameters to RuntimeException! I'm not telling you you should enjoy doing this, mind, just that it's possible.