java संकलक त्रुटि के बिना एकाधिक वापसी बयान




compiler-errors return (7)

यह एक साक्षात्कार सवाल था:

public class Demo {

    public static void main(String[] args) {
        System.out.println(foo());
    }

    static String foo() {
        try {
            return "try ...";
        } catch (Exception e) {
            return "catch ...";
        } finally {
            return "finally ..."; //got as result
        }
    }
}

मेरा सवाल यह है कि कोई संकलन समय त्रुटियां क्यों नहीं हैं। जब मेरे finally ब्लॉक में रिटर्न स्टेटमेंट होता है, तो finally में try और catch बजाय इसे वापस करने के लिए बाध्य किया जाता है। मैंने इस कोड को -Xlint विकल्प के साथ संकलित करने का प्रयास किया, यह एक चेतावनी देता है।

warning: [finally] finally clause cannot complete normally

केवल 1 के बाद से कोई संकलन समय त्रुटि नहीं है और return स्टेटमेंट का बिल्कुल 1 वास्तव में कॉलिंग कोड पर नियंत्रण वापस कर देगा।

जैसा कि @ हूपजे समझाया गया है, try या catch भीतर return पहले निष्पादित होगी, उनके संबंधित रिटर्न स्टेटमेंट भी निष्पादित होगा। लेकिन कॉलिंग कोड पर वापस नियंत्रण वापस करने से पहले, यह finally ब्लॉक निष्पादित करेगा। अब, यह block कुछ भी return है, इसलिए यह वापसी पिछले एक को ओवरराइड करता है।


यह अनिवार्य रूप से वही है:

public boolean someMethod(){
        if(1 == 1){
            return true;
        }
        return false;
}

यह एक संकलन त्रुटि नहीं देगा, हालांकि यह एक चेतावनी देगा। संकलक केवल तभी त्रुटि देगा जब कोई रिटर्न स्टेटमेंट निष्पादित नहीं किया जा सकता है।


इसे चलाने का प्रयास करें:

यह प्रिंट करेगा: 1, 2, 3 और फिर शून्य अपवाद द्वारा एक विभाजन फेंक दें

public class Demo {
  public static void main(String[] args) {
    System.out.println(foo());
  }
  public static String print(int a){
    System.out.println(a);
    return String.valueOf(a/0);
  }
  static String foo() {
    try {
      return print(1);
    } catch (Exception e) {
      return print(2);
    } finally {
      return  print(3);
    }
  }
}

आपका कोड ठीक काम करता है क्योंकि कोशिश, पकड़ और अंत में ब्लॉक में केवल एक ही वापसी कथन है। संकलन त्रुटि तब होगी जब आप प्रयास में से किसी एक के अंदर दो रिटर्न स्टेटमेंट लिखने का प्रयास करें, पकड़ें या आखिरकार ब्लॉक करें कि एक पहुंच योग्य वापसी कथन है।


यह संकलन त्रुटि नहीं देता है क्योंकि इसे जावा भाषा विशिष्टता द्वारा अनुमत किया जाता है। हालांकि, यह एक चेतावनी संदेश देता है क्योंकि finally ब्लॉक में return स्टेटमेंट समेत एक बुरा विचार है।

आपके उदाहरण में क्या होता है निम्नलिखित है। try ब्लॉक में return विवरण निष्पादित किया गया है। हालांकि, finally ब्लॉक को हमेशा निष्पादित किया जाना चाहिए ताकि catch ब्लॉक समाप्त होने के बाद इसे निष्पादित किया जा सके। वहां होने वाले return स्टेटमेंट में पिछले return स्टेटमेंट के परिणाम को ओवरराइट किया गया है, और इसलिए विधि दूसरा परिणाम देता है।

इसी तरह एक finally ब्लॉक आमतौर पर एक अपवाद फेंकना नहीं चाहिए। यही कारण है कि चेतावनी का कहना है कि finally ब्लॉक सामान्य रूप से पूरा होना चाहिए, यानी, बिना किसी return या अपवाद फेंकना।


यह जावा भाषा विशिष्टता में वर्णित है:

§14.17

finally खंड के पूर्ण होने से return स्टेटमेंट द्वारा शुरू किए गए नियंत्रण के हस्तांतरण में बाधा return है।

§14.20.2

यदि try ब्लॉक का निष्पादन सामान्य रूप से पूर्ण होता है, तो finally ब्लॉक निष्पादित होता है, और फिर कोई विकल्प होता है:

  • यदि finally ब्लॉक सामान्य रूप से पूरा हो जाता है, तो try कथन सामान्य रूप से पूरा होता है।
  • यदि finally ब्लॉक कारण एस के लिए अचानक समाप्त हो जाता है, तो try कथन कारण एस के लिए अचानक समाप्त हो जाता है।

यदि किसी भी अन्य कारण आर के लिए try ब्लॉक का निष्पादन अचानक समाप्त हो जाता है, तो finally ब्लॉक निष्पादित किया जाता है, और फिर कोई विकल्प होता है:

  • यदि finally ब्लॉक सामान्य रूप से पूरा हो जाता है, तो try कथन कारण आर के लिए अचानक समाप्त हो जाता है।
  • यदि finally ब्लॉक कारण एस के लिए अचानक समाप्त हो जाता है, तो try कथन कारण एस (और कारण आर को त्याग दिया जाता है) के लिए अचानक समाप्त हो जाता है।

शानदार प्रश्न .. मेरे ज्ञान के मुताबिक कोशिश और पकड़ ब्लॉक का रिटर्न स्टेटमेंट आखिर में स्थानांतरित कर दिया गया है यदि आपने आखिरकार अपने कोड पर ब्लॉक जोड़ा है। इस तरह इसका काम है।

तो इस मामले में सभी कोड लाइन निष्पादित हो रही हैं और आप डिबगिंग का प्रयास कर सकते हैं। कोड के नीचे मैंने कोशिश की सभी तीन ब्लॉक।

public class Main {

    public static void main(String[] args) {
        System.out.println(foo());
    }
    static String foo() {
        try {
            throw new Exception();
        } catch (Exception e) {
            return "catch ...";
        } finally {
            return "finally ..."; //got as result
        }
    }
}

आप नीचे दिए गए लिंक से विचार प्राप्त कर सकते हैं। एकाधिक रिटर्न: कौन सा अंतिम रिटर्न वैल्यू सेट करता है?





try-catch-finally