ホームページ >Java >&#&チュートリアル >Java 8 ラムダ式内で呼び出されたメソッドからスローされたチェック例外を処理する方法は?
Java 8 Lambda-Streams: 例外のあるメソッドによるフィルタリング
ラムダ式内で呼び出されたメソッドからスローされた例外をインターセプトすることは、 Java 8 ストリーム処理機能が強化されました。この問題は、これらのメソッドがチェック例外を宣言し、それを囲んでいるラムダがスローすることを許可されていない場合に発生します。
次の例を考えてみましょう。
<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>
この問題を解決するには、ラムダ式をエスケープする前に例外をキャプチャする必要があります。これは、チェックされた例外をチェックされていない例外に変換するカスタム関数でラムダをラップすることで実現できます:
<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>
これらの手法を適用することで、次のようなラムダ式を利用することができます。チェック例外を宣言するメソッド。これにより、コードの明確さと例外処理機能の両方が保証されます。
以上がJava 8 ラムダ式内で呼び出されたメソッドからスローされたチェック例外を処理する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。