Java 8 Lambda-Streams:按带有异常的方法进行过滤
拦截从 lambda 表达式中调用的方法抛出的异常在利用增强的 Java 8 流处理能力。当这些方法声明检查异常时,就会出现问题,而封闭的 lambda 不允许抛出异常。
考虑以下示例:
<code class="java">class Bank { public Set<String> getActiveAccountNumbers() throws IOException { Stream<Account> s = accounts.values().stream(); s = s.filter(a -> a.isActive()); Stream<String> ss = s.map(a -> a.getNumber()); return ss.collect(Collectors.toSet()); } } interface Account { boolean isActive() throws IOException; String getNumber() throws IOException; }</code>
要编译此代码,需要捕获isActive 和 getNumber 方法中潜在的 IOException。但是,仅处理 try-catch 块中的异常(如下所示)仍然会导致编译错误:
<code class="java">class Bank { public Set<String> getActiveAccountNumbers() throws IOException { try { Stream<Account> s = accounts.values().stream(); s = s.filter(a -> a.isActive()); Stream<String> ss = s.map(a -> a.getNumber()); return ss.collect(Collectors.toSet()); } catch (IOException ex) { // Exception not caught } } }</code>
要解决此问题,必须在异常转义 lambda 表达式之前捕获异常。这可以通过将 lambda 包装在自定义函数中来实现,该函数将已检查的异常转换为未检查的异常:
<code class="java">s = s.filter(a -> { try { return a.isActive(); } catch (IOException e) { throw new UncheckedIOException(e); // Translated to an unchecked exception } });</code>
或者,可以采用避免包装的方法:
<code class="java">public static <T> T uncheckCall(Callable<T> callable) { try { return callable.call(); } catch (Exception e) { sneakyThrow(e); // Potentially throws the exception return null; // Unreachable, but necessary to satisfy the compiler } }</code>
这个函数本质上是欺骗编译器,让其相信不会抛出已检查的异常,从而允许在更高级别上优雅地处理异常。
<code class="java">return s.filter(a -> uncheckCall(a::isActive)) .map(Account::getNumber) .collect(toSet());</code>
通过应用这些技术,可以利用 lambda 表达式声明已检查异常的方法,确保代码清晰性和异常处理能力。
以上是如何处理 Java 8 Lambda 表达式中调用的方法引发的检查异常?的详细内容。更多信息请关注PHP中文网其他相关文章!