为何Java Stream外层try-catch无法处理异常?附相关疑问
Java Stream中try-catch位置影响异常捕获的原因分析
问题场景
编写Java Stream代码时,在外层用try-catch捕获AddressException会提示“Unhandled Exception: AddressException”错误,但把try-catch放在map方法内部时代码能正常编译运行,同时想知道匿名内部类是否会有相同表现。
代码示例:
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails){ List<InternetAddress> internetAddresses = new ArrayList<>(); internetAddresses = toEmails.stream().map(a->{ InternetAddress ia = null; try{ ia = new InternetAddress(a); } catch (AddressException e) { } return ia; }).collect(Collectors.toList()); return internetAddresses; }
原因解析
1. Stream的map方法对异常的限制
Stream.map方法接收的是Function<T, R>接口的实现,该接口的apply(T t)方法签名没有声明抛出任何受检异常。而AddressException属于受检异常,Java编译器要求:受检异常必须被显式捕获,或者在方法签名中声明抛出。
当你把try-catch放在外层时,lambda表达式内部抛出的AddressException并没有被捕获——因为lambda是独立的函数体,属于apply方法的实现,而apply方法不允许抛出未声明的受检异常,所以编译器直接报错,提示异常未处理。
只有在lambda内部添加try-catch,才能在apply方法内部完成受检异常的处理,满足编译器的要求,代码才能正常编译。
2. 匿名内部类的表现
匿名内部类的表现和lambda完全一致。如果用匿名内部类实现Function接口的apply方法,同样不能抛出超过接口方法声明的受检异常。比如下面的代码同样会编译报错:
// 错误示例:匿名内部类中抛出未处理的受检异常 internetAddresses = toEmails.stream().map(new Function<String, InternetAddress>() { @Override public InternetAddress apply(String a) { // 此处抛出AddressException,未捕获且apply方法未声明抛出,编译报错 return new InternetAddress(a); } }).collect(Collectors.toList());
必须在匿名内部类的apply方法内部添加try-catch处理AddressException,代码才能正常编译,和lambda的逻辑完全相同。
内容的提问来源于stack exchange,提问作者Jithin M V
相关产品推荐
相关产品推荐

