Rumah  >  Artikel  >  Java  >  Bagaimana Mengendalikan Pengecualian Diperiksa yang Dilemparkan daripada Kaedah yang Dikenakan Dalam Ungkapan Lambda Java 8?

Bagaimana Mengendalikan Pengecualian Diperiksa yang Dilemparkan daripada Kaedah yang Dikenakan Dalam Ungkapan Lambda Java 8?

Linda Hamilton
Linda Hamiltonasal
2024-10-26 12:16:29705semak imbas

How to Handle Checked Exceptions Thrown from Methods Invoked Within Java 8 Lambda Expressions?

Java 8 Lambda-Stream: Menapis mengikut Kaedah dengan Pengecualian

Memintas pengecualian yang dilemparkan daripada kaedah yang digunakan dalam ungkapan lambda memberikan cabaran apabila menggunakan keupayaan pemprosesan aliran Java 8 dipertingkatkan. Isu timbul apabila kaedah ini mengisytiharkan pengecualian yang diperiksa, yang mana lambda yang dilampirkan tidak dibenarkan untuk membuang.

Pertimbangkan contoh berikut:

<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>

Untuk menyusun kod ini, adalah perlu untuk menangkap potensi IOException dalam kaedah isActive dan getNumber. Walau bagaimanapun, hanya mengendalikan pengecualian dalam blok cuba-tangkap, seperti yang ditunjukkan di bawah, masih menghasilkan ralat kompilasi:

<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>

Untuk menyelesaikan isu ini, pengecualian mesti ditangkap sebelum ia terlepas daripada ungkapan lambda. Ini boleh dicapai dengan membalut lambda dalam fungsi tersuai yang menterjemahkan pengecualian yang ditandakan kepada yang tidak ditanda:

<code class="java">s = s.filter(a -> {
    try {
        return a.isActive();
    } catch (IOException e) {
        throw new UncheckedIOException(e); // Translated to an unchecked exception
    }
});</code>

Sebagai alternatif, pendekatan yang mengelakkan pembalut boleh digunakan:

<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>

Fungsi ini pada asasnya menipu pengkompil untuk mempercayai bahawa tiada pengecualian yang diperiksa boleh dilemparkan, membenarkan pengecualian dikendalikan dengan anggun pada tahap yang lebih tinggi.

<code class="java">return s.filter(a -> uncheckCall(a::isActive))
        .map(Account::getNumber)
        .collect(toSet());</code>

Dengan menggunakan teknik ini, adalah mungkin untuk menggunakan ungkapan lambda dengan kaedah yang mengisytiharkan pengecualian yang disemak, memastikan kejelasan kod dan keupayaan pengendalian pengecualian.

Atas ialah kandungan terperinci Bagaimana Mengendalikan Pengecualian Diperiksa yang Dilemparkan daripada Kaedah yang Dikenakan Dalam Ungkapan Lambda Java 8?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn