美文网首页
Java8 stream中使用检查异常

Java8 stream中使用检查异常

作者: tenlee | 来源:发表于2019-11-12 11:27 被阅读0次

    搬运工 https://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams

    题主希望这段代码能够编译通过

     public List<Class> getClasses() throws ClassNotFoundException {
    
            List<Class> classes =
                Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
                    .map(className -> Class.forName(className))
                    .collect(Collectors.toList());
            return classes;
        }
    
    image.png
    但是lambda表达式中不能有检查异常,必须要try...catch...
    public List<Class> getClasses() throws ClassNotFoundException {
    
            List<Class> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String").map(className -> {
                try {
                    return Class.forName(className);
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
            return classes;
        }
    

    看起来很不优雅呀。
    于是有个大神写了LambdaExceptionUtil利用泛型的擦除机制

    import java.util.function.BiConsumer;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Supplier;
    
    
    public class LambdaExceptionUtil {
        @FunctionalInterface
        public interface Consumer_WithExceptions<T, E extends Exception> {
            void accept(T t) throws E;
        }
    
        @FunctionalInterface
        public interface BiConsumer_WithExceptions<T, U, E extends Exception> {
            void accept(T t, U u) throws E;
        }
    
        @FunctionalInterface
        public interface Function_WithExceptions<T, R, E extends Exception> {
            R apply(T t) throws E;
        }
    
        @FunctionalInterface
        public interface Supplier_WithExceptions<T, E extends Exception> {
            T get() throws E;
        }
    
        @FunctionalInterface
        public interface Runnable_WithExceptions<E extends Exception> {
            void run() throws E;
        }
    
        /**
         * .forEach(rethrowConsumer(name -> System.out.println(Class.forName(name)))); or .forEach(rethrowConsumer(ClassNameUtil::println));
         */
        public static <T, E extends Exception> Consumer<T> rethrowConsumer(Consumer_WithExceptions<T, E> consumer)
            throws E {
            return t -> {
                try {
                    consumer.accept(t);
                } catch (Exception exception) {
                    throwAsUnchecked(exception);
                }
            };
        }
    
        public static <T, U, E extends Exception> BiConsumer<T, U> rethrowBiConsumer(
            BiConsumer_WithExceptions<T, U, E> biConsumer) throws E {
            return (t, u) -> {
                try {
                    biConsumer.accept(t, u);
                } catch (Exception exception) {
                    throwAsUnchecked(exception);
                }
            };
        }
    
        /**
         * .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
         */
        public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function)
            throws E {
            return t -> {
                try {
                    return function.apply(t);
                } catch (Exception exception) {
                    throwAsUnchecked(exception);
                    return null;
                }
            };
        }
    
        /**
         * rethrowSupplier(() -> new StringJoiner(new String(new byte[]{77, 97, 114, 107}, "UTF-8"))),
         */
        public static <T, E extends Exception> Supplier<T> rethrowSupplier(Supplier_WithExceptions<T, E> function)
            throws E {
            return () -> {
                try {
                    return function.get();
                } catch (Exception exception) {
                    throwAsUnchecked(exception);
                    return null;
                }
            };
        }
    
        /**
         * uncheck(() -> Class.forName("xxx"));
         */
        public static void uncheck(Runnable_WithExceptions t) {
            try {
                t.run();
            } catch (Exception exception) {
                throwAsUnchecked(exception);
            }
        }
    
        /**
         * uncheck(() -> Class.forName("xxx"));
         */
        public static <R, E extends Exception> R uncheck(Supplier_WithExceptions<R, E> supplier) {
            try {
                return supplier.get();
            } catch (Exception exception) {
                throwAsUnchecked(exception);
                return null;
            }
        }
    
        /**
         * uncheck(Class::forName, "xxx");
         */
        public static <T, R, E extends Exception> R uncheck(Function_WithExceptions<T, R, E> function, T t) {
            try {
                return function.apply(t);
            } catch (Exception exception) {
                throwAsUnchecked(exception);
                return null;
            }
        }
    
        @SuppressWarnings("unchecked")
        private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
            throw (E)exception;
        }
    
    }
    

    然后就可以这样写了,检查异常不是只能在lambda表达式用`try...catch...``,也能放在方法签名了。

    public List<Class> getClasses() throws ClassNotFoundException {
    
            List<Class> classes =
                Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
                    .map(LambdaExceptionUtil.rethrowFunction(className -> Class.forName(className)))
                    .collect(Collectors.toList());
            return classes;
        }
    

    相关文章

      网友评论

          本文标题:Java8 stream中使用检查异常

          本文链接:https://www.haomeiwen.com/subject/ccmfictx.html