जावा -8 में कई अपवादों को पकड़ना


71

मल्टी-कैच फीचर को आजमाते हुए मैंने अपने m1()तरीके में पाया कि सब कुछ उम्मीद के मुताबिक ठीक चल रहा है।

हालांकि, m2()एक ही कोड में संकलन नहीं है। मैंने कोड की लाइनों की संख्या को कम करने के लिए सिंटैक्स को बदल दिया है।

public class Main {

    public int m1(boolean bool) {
        try {
            if (bool) {
                throw new Excep1();
            }
            throw new Excep2();
            //This m1() is compiling  abs fine.
        } catch (Excep1 | Excep2 e) {
            return 0;
        }
    }

    public int m2(boolean b) {
        try {
            throw b ? new Excep1() : new Excep2();
            //This one is not compiling.
        } catch (Excep1 | Excep2 e) {
            return 0;
        }
    }

    private static interface I {
    }

    private static class Excep1 extends Exception implements I {
    }

    private static class Excep2 extends Exception implements I {
    }
}

विधि m2()संकलन क्यों नहीं ?


22
आपको कौन सी संकलन त्रुटि मिल रही है?
गाविन

जवाबों:


79

अभिव्यक्ति का प्रकार

b ? new Excep1() : new Excep2()

के Exceptionबाद से, का सामान्य सुपरस्क्रिप्ट है Excep1और Excep2

हालांकि, आप पकड़ नहीं रहे हैं Exception, इसलिए कंपाइलर इसके बारे में शिकायत करता है।

यदि आप पकड़ते हैं Exception, तो यह संकलन पास करेगा:

public int m2(boolean b) {
    try {
        throw b ? new Excep1() : new Excep2();
    } catch (Exception e) {
        return 0;
    }
}

मैंने जेएलएस प्रविष्टि को खोजने की कोशिश की जो आपके उदाहरण में सशर्त टर्नरी अभिव्यक्ति के प्रकार की व्याख्या करती है।

मुझे केवल इतना पता चला कि यह विशेष अभिव्यक्ति 15.25.3 है। संदर्भ सशर्त अभिव्यक्ति

मुझे पूरी तरह से यकीन नहीं है कि यह पॉली एक्सप्रेशन या स्टैंडअलोन एक्सप्रेशन के रूप में गिना जाता है। मुझे लगता है कि यह स्टैंडअलोन है (क्योंकि पॉली एक्सप्रेशंस में एक असाइनमेंट संदर्भ या एक मंगलाचरण संदर्भ शामिल है, और मुझे नहीं लगता कि एक throwबयान उन दोनों में से एक के रूप में गिना जाता है)।

एक स्टैंडअलोन अभिव्यक्ति के लिए: "यदि दूसरे और तीसरे ऑपरेंड में एक ही प्रकार (जो अशक्त प्रकार हो सकता है), तो वह सशर्त अभिव्यक्ति का प्रकार है।"

आपके मामले में, दूसरे और तीसरे ऑपरेंड तीन आम प्रकार है - Object, Throwableऔर Exception- अभिव्यक्ति के प्रकार के बाद के दो में से एक होना चाहिए, क्योंकि "एक फेंक बयान में अभिव्यक्ति या तो एक चर या एक संदर्भ प्रकार के मान दर्शाने चाहिए जो थ्रोएबल के प्रकार के लिए असाइन करने योग्य (§5.2) है। "

ऐसा प्रतीत होता है कि संकलक सबसे विशिष्ट सामान्य प्रकार ( Exception) उठाता है , और इसलिए catch (Exception e)संकलन त्रुटि को हल करता है।

मैंने आपके दो कस्टम अपवादों को दो उप-वर्गों के साथ प्रतिस्थापित करने का भी प्रयास किया है IOException, जिस स्थिति catch (IOException e)में संकलन त्रुटि को हल करता है।


11
@ द्वितीय और तृतीय दोनों ऑपरेंड के लिए टर्नरी सशर्त अभिव्यक्ति का प्रकार सामान्य होना चाहिए। इसलिए यह नहीं हो सकता है Excep1या Excep2। यह केवल हो सकता है Exception
इरान

2
15.25.3 में अंतिम बुलेट बिंदु का जवाब है: "अन्यथा, दूसरे और तीसरे ऑपरेशंस क्रमशः S1 और S2 प्रकार के हैं। T1 वह प्रकार है जो मुक्केबाजी रूपांतरण को S1 में लागू करने से परिणामित होता है, और T2 का प्रकार होता है। बॉक्सिंग रूपांतरण को S2 में लागू करने से। सशर्त अभिव्यक्ति का प्रकार कैप्चर रूपांतरण (.15.1.10) को लुब (T1, T2) पर लागू करने का परिणाम है। " lub यहाँ Least Upper Bound है, जो दो अभिव्यक्तियों के प्रकार साझा करने के लिए निकटतम सामान्य सुपरपाइप है।
अमलियॉ

22

आप इस लाइन के साथ कंपाइलर को भ्रमित कर रहे हैं:

throw b ? new Excep1() : new Excep2();

संकलक देखता है कि एक्सप्रेशन 1 और अपवर्ज 2 के बीच अभिव्यक्ति का परिणाम (फेंक के बाईं ओर) सामान्य सुपर क्लास है, जो अपवाद है, और इसलिए आप जिस प्रभावी प्रकार को फेंक रहे हैं वह अपवाद है। कैच स्टेटमेंट यह नहीं उठा सकता है कि आप Excep1 या असाधारण 2 को फेंकना चाहते हैं।


4

जावा आपको सभी अपवाद प्रकारों को पकड़ने या घोषित करने के लिए प्रतिबंधित करता है, जो विधि फेंकता है,

यह दोनों के लिए आम माता-पिता के लिए खोज (/ सभी) अपवाद है और आप को पकड़ने के लिए या घोषित फेंकता के रूप में, उदाहरण के लिए अगर उम्मीद Excep1फैलीThrowable आप करते हैं आपको भी फेंकना होगा

पहले मामले में जावा सुनिश्चित है कि आप या तो फेंक रहे हैं Excep1याExcep2

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.