Java8 Lambda异常处理:Lambda调用方如何处理AddressException
没问题,我来给你拆解一下Lambda里处理这个异常的具体方案,分步骤来就很清晰了:
第一步:确保
parseEmailAddress正确抛出AddressException 首先得让你的解析方法在遇到无效邮箱时,明确抛出AddressException(假设这是一个checked异常)。举个示例实现:
import javax.mail.internet.AddressException; public static String parseEmailAddress(String email) throws AddressException { // 这里替换成你实际的邮箱校验逻辑,比如格式校验、域名验证等 if (email == null || !email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$")) { throw new AddressException("无效的邮箱地址: " + email); } // 返回处理后的合法邮箱(比如统一转小写) return email.toLowerCase(); }
第二步:Lambda调用方的优雅异常处理
Lambda表达式里如果要处理checked异常,不能直接往外抛(会编译报错),所以得在Lambda内部先捕获异常,收集有效邮箱,最后再判断列表是否为空并抛出异常。这里给你两种实现方式:
方式一:传统forEach + 内部try-catch
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.mail.internet.AddressException; public class EmailProcessor { public static void main(String[] args) throws AddressException { List<String> rawEmailList = Arrays.asList("alice@example.com", "invalid-email", "bob@test.org", "no-at-sign.com"); List<String> validEmails = new ArrayList<>(); // 遍历处理每个邮箱,捕获无效邮箱的异常 rawEmailList.forEach(email -> { try { validEmails.add(parseEmailAddress(email)); } catch (AddressException e) { // 这里可以记录日志、告警,或者只是简单打印提示 System.err.println("跳过无效邮箱: " + e.getMessage()); } }); // 检查最终有效列表是否为空,为空则抛出异常 if (validEmails.isEmpty()) { throw new AddressException("所有邮箱地址均无效,无有效邮箱可继续处理"); } // 后续业务逻辑:使用validEmails列表 System.out.println("有效邮箱列表: " + validEmails); } // 这里放parseEmailAddress方法... }
方式二:用Stream API简化处理(更优雅)
如果习惯用Stream的话,可以把校验逻辑包装成返回Optional的形式,过滤掉无效项,最后收集结果:
import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.mail.internet.AddressException; public class EmailProcessor { public static void main(String[] args) throws AddressException { List<String> rawEmailList = Arrays.asList("alice@example.com", "invalid-email", "bob@test.org", "no-at-sign.com"); List<String> validEmails = rawEmailList.stream() .map(email -> { try { return Optional.of(parseEmailAddress(email)); } catch (AddressException e) { System.err.println("跳过无效邮箱: " + e.getMessage()); return Optional.empty(); } }) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); // 空列表检查 if (validEmails.isEmpty()) { throw new AddressException("所有邮箱地址均无效,无有效邮箱可继续处理"); } // 后续业务逻辑 System.out.println("有效邮箱列表: " + validEmails); } // 这里放parseEmailAddress方法... }
关键注意点
- Lambda内部必须捕获checked异常:因为Lambda的函数式接口(比如
Consumer)的方法签名不允许抛出checked异常,所以必须在Lambda内部处理掉,或者包装成unchecked异常抛出(不过不推荐,会破坏异常语义)。 - 空列表的异常抛出:在收集完有效邮箱后,主动判断列表是否为空,抛出
AddressException,这样上层调用方可以统一处理这个业务异常。 - 日志记录:处理无效邮箱时,最好不要只打印控制台,而是用日志框架(比如SLF4J)记录错误信息,方便后续排查问题。
内容的提问来源于stack exchange,提问作者user1578872
相关产品推荐
相关产品推荐

