java मैं जावा 8 लैम्ब्डा अभिव्यक्ति में एक अपवाद क्यों नहीं फेंक सकता?




exception lambda (2)

इस सवाल का पहले से ही उत्तर दिया गया है:

मैं जावा 8 में उन्नत हुआ और एक नया लाम्ब्डा अभिव्यक्ति के साथ मानचित्र के माध्यम से एक सरल पुनरावृत्ति को बदलने की कोशिश की। पाश रिक्त मानों के लिए खोज करता है और यदि एक पाई जाती है तो अपवाद फेंकता है पुराने जावा 7 कोड इस तरह दिखता है:

for (Map.Entry<String, String> entry : myMap.entrySet()) {
    if(entry.getValue() == null) {
        throw new MyException("Key '" + entry.getKey() + "' not found!");
    }
}

और जावा 8 में इसे बदलने का मेरा प्रयास इस तरह दिखता है:

myMap.forEach((k,v) -> {
    if(v == null) {
        // OK
        System.out.println("Key '" + k+ "' not found!");

        // NOK! Unhandled exception type!
        throw new MyException("Key '" + k + "' not found!");
    }
});

क्या कोई यह समझा सकता है कि throw कथन यहाँ क्यों नहीं है और यह कैसे ठीक किया जा सकता है?

ग्रहण का त्वरित-तय सुझाव मुझे सही नहीं दिखता ... यह केवल एक try-catch ब्लॉक के साथ throw वक्तव्य को घेरता है:

myMap.forEach((k,v) -> {
    if(v == null) {
        try {
            throw new MyException("Key '" + k + "' not found!");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
});

आपको चेक अपवादों को फेंकने की अनुमति नहीं है क्योंकि void accept(T t, U u) विधि में BiConsumer<T, U> इंटरफ़ेस कोई भी अपवाद नहीं फेंकता है। और, जैसा कि आप जानते हैं, forEach इस तरह का प्रकार लेता है

public void forEach(BiConsumer<? super K, ? super V> action) { ... }
                         |
                         V
@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u); // <-- does throw nothing
}

यह सच है जब हम जाँच अपवादों के बारे में बात कर रहे हैं। लेकिन आपको एक अनियंत्रित अपवाद फेंकने की अनुमति है, उदाहरण के लिए, एक IllegalArgumentException अपवाद:

new HashMap<String, String>()
    .forEach((a, b) -> { throw new IllegalArgumentException(); });

आप लैम्ब्दास में अपवाद फेंक सकते हैं।

लैम्ब्डा द्वारा कार्यान्वित कार्यात्मक इंटरफ़ेस के रूप में एक लैम्ब्डा को समान अपवाद फेंकने की अनुमति है।

यदि कार्यात्मक इंटरफ़ेस की विधि में कोई फेंकता नहीं है, तो लैम्ब्डा चेकेड अपवाद को नहीं फेंक सकता है। (आप अभी भी रनटाइम अपवाद निकाल सकते हैं)

आपके विशेष मामले में, Map.forEach BiConsumer के लिए एक पैरामीटर के रूप में एक Map.forEach का उपयोग करता है, BiConsumer परिभाषित किया गया है:

public interface BiConsumer<T, U> {
    void accept(T t, U u);
}

इस फ़ंक्शनल इंटरफ़ेस के लिए एक लैम्ब्डा अभिव्यक्ति चेकडेक्स एक्सपेशेशन को नहीं फेंक सकता।

java.util.function पैकेज में परिभाषित कार्यात्मक इंटरफेस के तरीकों अपवाद फेंक नहीं करते हैं, लेकिन आप अन्य कार्यात्मक इंटरफेस का उपयोग कर सकते हैं या अपवाद फेंकने में सक्षम होने के लिए अपना स्वयं का बना सकते हैं, अर्थात यह अंतरफलक दिया गया है:

public interface MyFunctionalInterface<T> {
    void accept(T t) throws Exception;
}

निम्नलिखित कोड कानूनी होगा:

MyFunctionalInterface<String> f = (s)->throw new Exception("Exception thrown in lambda"); 






java-8