lambda表达式无法抛出异常

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

public class BeanUtil {

    public static  List copyList(List source , Class clazz) throws Exception {
        if(CollectionUtils.isEmpty(source)){
            return null;
        }
        List 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 mapper)方法,参数为Function实例,源码:

public final  Stream map(Function mapper) {
        Objects.requireNonNull(mapper);
        return new StatelessOp(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
            @Override
            Sink opWrapSink(int flags, Sink sink) {
                return new Sink.ChainedReference(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抛异常。

你可能感兴趣的:(Java)