lambda表达式无法抛出异常

探讨在Java中使用Lambda表达式时,为何无法在方法声明中使用throws关键字来抛出异常,而必须在Lambda体内使用try-catch进行异常捕获。深入分析Stream API的map方法与Function接口的apply方法之间的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:在一个方法中使用了lambda表达式,表达式中需要捕获异常,使用throws关键字发现并不起作用,必须使用trycatch才行

public class BeanUtil {

    public static <T,R> List<R> copyList(List<T> source , Class<R> clazz) throws Exception {
        if(CollectionUtils.isEmpty(source)){
            return null;
        }
        List<R> rList = source.stream().map(s ->{
            R r = null;

                r = clazz.newInstance();
            
            BeanUtils.copyProperties(s,r);
            return r;
        } ).collect(Collectors.toList());
        return rList;
    }
}

如上,虽然在方法copyList上使用了throws Exception但是已经无法通过编译,提示有未处理异常,正确代码如下,使用trycatch

 try {
                r = clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }

提问:为何lambda表达式中的异常不能在外部throws,只能内部捕获?

看Stream.map(Function<? super T, ? extends R> mapper)方法,参数为Function实例,源码:

public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {
        Objects.requireNonNull(mapper);
        return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
                return new Sink.ChainedReference<P_OUT, R>(sink) {
                    @Override
                    public void accept(P_OUT u) {
                        downstream.accept(mapper.apply(u));
                    }
                };
            }
        };
    }

最终调用了Function中的apply方法,事实上,我们在map方法中写的s ->{……},其实就是重写apply方法的实现,而抛出异常的语句"r = clazz.newInstance()"就是在apply方法中抛出的,就是说在异常语句和copyList方法之间还存在一个apply方法,而apply方法是不允许向上抛出异常的,所以copyList方法自然不能使用throws抛异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值