首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在Java8的Consumer中抛出异常

在Java8的Consumer中抛出异常

作者头像
Erwin
发布2021-03-04 10:50:40
3.7K1
发布2021-03-04 10:50:40
举报
文章被收录于专栏:啸天"s blog啸天"s blog

最近在实现公司内部一个通用svn数据工具类,其中有段代码是拿到当前更新后的数据进行下一步操作,用的是java8的Consumer实现的,代码如下:

public void save(final DTO dto, final Consumer<List<T>> cons) throws Exception

这段代码一开始并没有什么问题,但是投入生产后发现有些异常数据导致服务器报错了,但是前台还是返回操作成功,debug查看后发现是异常被调用方吃掉了,原因了原生Consumer不支持异常抛出,只能内部处理,接到反馈后,自己测试确实能复现,查看Consumer源码发现原生确实不支持抛出,查阅网络资料,发现只能重写一个Consumer方法,特此记录一下

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);//并没有异常处理

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

解决方法:

  1. 新建一个ThrowingConsumer.class文件
import java.util.function.Consumer;

/**
 * @ClassName: ThrowingConsumer
 * @Description: 重写Java8的Consumer中的异常抛出
 * @author:Erwin.Zhang
 * @date: 2021-03-01 10:59:19
 */
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {

    @Override
    default void accept(final T e) {
        try {
            accept0(e);
        } catch (Throwable ex) {
            Throwing.sneakyThrow(ex);
        }
    }

    void accept0(T e) throws Throwable;

}

新建一个处理异常的Throwing.class

import javax.validation.constraints.NotNull;

* @ClassName: Throwing
* @Description: 在Java8的Consumer中抛出异常
* @author:Erwin.Zhang
* @date: 2021-03-01 10:58:31
 */
public class Throwing {
    private Throwing() {}

    @NotNull
    public static <T> Consumer<T> rethrow(@NotNull final ThrowingConsumer<T> consumer) {
        return consumer;
    }

    /**
     * The compiler sees the signature with the throws T inferred to a RuntimeException type, so it allows the unchecked
     * exception to propagate.
     *
     * http://www.baeldung.com/java-sneaky-throws
     */
    @SuppressWarnings("unchecked")
    @NotNull
    public static <E extends Throwable> void sneakyThrow(@NotNull final Throwable ex) throws E {
        throw (E)ex;
    }
}

使用方法

import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException;

* @ClassName: ThrowingTest
* @Description: 测试异常抛出
* @author:Erwin.Zhang
* @date: 2021-03-01 11:00:38
 */
public class ThrowingTest {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void testRethrow() {
        thrown.expect(IOException.class);
        thrown.expectMessage("i=3");

        Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
            int i = e;
            if (i == 3) {
                throw new IOException("i=" + i);
            }
        }));
    }

    @Test(expected = IOException.class)
    public void testSneakyThrow() {
        Throwing.sneakyThrow(new IOException());
    }

    @Test
    public void testThrowingConsumer() {
        thrown.expect(IOException.class);
        thrown.expectMessage("i=3");

        Arrays.asList(1, 2, 3).forEach((ThrowingConsumer<Integer>)e -> {
            int i = e;
            if (i == 3) {
                throw new IOException("i=" + i);
            }
        });
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档