Is a good solution to use the proven decorator function in the Stream API?

I use the Java 8 Stream API, and as we know, it does not support checked exceptions inside any functional interface inside java.util.function.

I usually have to use a method with checked exceptions inside stream operations, and I wrote a CheckedFunction decoder to use inside these operations:

import java.util.function.BiFunction; import java.util.function.Function; public interface CheckedFunction<T, R, E extends Throwable> { R apply(T t) throws E; static <T, R, CE extends Throwable, UCE extends RuntimeException> Function<T, R> checked( CheckedFunction<T, R, CE> checked, Function<CE, UCE> exceptionHandler) { return (t) -> { try { return checked.apply(t); } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { // can't catch - compiler error if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } throw exceptionHandler.apply((CE) e); } }; } } 

so I can use it in such cases:

 entities.stream() .map(checked((entity) -> someResultChecked(entity), // throws IOException (entity, e) -> { // e is of type IOException log.error("exception during checked method of " + entity, e); return new UncheckedIOException(e); })) .map(checked((entity) -> saveToDb(entity), // throws SQLException (entity, e) -> { // e is of type SQLException log.error("exception during saving " + entity, e); return new UncheckedSQLException(e); })) .map(checked((entity) -> manyExceptionMethod(entity), // throws IOException, SQLException (entity, e) -> { // e is of type Throwable return new RuntimeException(e); })) 

It will package any thrown exception in unchecked, but I know that if a method throws more than one exception, it will remove Throwable, I will use it in simple cases.

Is this a good idea, or can I run into hidden obstacles?

UPDATED: Reusing RuntimeExceptions.

I also found a clearer solution in jOOL with InterruptedException handling that could cause inconsistent behavior if ignored: https://github.com/jOOQ/jOOL/blob/master/src/main/java/org/jooq/lambda/ Unchecked.java

+6
source share
1 answer

You will get a ClassCastException if anything other than an IOException is Throwable , since you catch all Throwable and pass them to the UncheckedIOException constructor, which only accepts an IOException as a parameter. Since catching an IOException in a functional type is such a general need, rather than trying to generalize, it is best to keep it simple and make it just for that checked exception. I would suggest that you rarely need to duplicate code to do the same for other checked exceptions.

 @FunctionalInterface public interface CheckedIOFunction<T,R> { R apply(T t) throws IOException; static <T, R> Function<T, R> toUnchecked(CheckedIOFunction<T, R> function) { return t -> { try { return function.apply(t); } catch (IOException ioe) { throw new UncheckedIOException(ioe); } }; } } 
0
source

All Articles