Java कैच कैच करें अंत में बिना कैच के ब्लॉक करें


125

मैं कुछ नए कोड की समीक्षा कर रहा हूं। कार्यक्रम में एक कोशिश और अंत में केवल ब्लॉक है। चूँकि कैच ब्लॉक को बाहर रखा गया है, अगर यह एक अपवाद या फेंकने योग्य चीज का सामना करता है, तो कोशिश ब्लॉक कैसे काम करता है? क्या यह सीधे अंततः ब्लॉक करने के लिए जाता है?



25
@ एमपी हर किसी को कोड समीक्षाएं करनी चाहिए और उनसे सवाल पूछना चाहिए कि कैसे सीखना और सुधारना है।
कार्ल प्रीचेट

जवाबों:


130

अगर कोशिश ब्लॉक में कोई भी कोड एक चेक किए गए अपवाद को फेंक सकता है, तो उसे विधि हस्ताक्षर के थ्रो क्लॉज में प्रकट होना होगा। अगर एक अनियंत्रित अपवाद को फेंक दिया जाता है, तो यह विधि से बाहर हो जाता है।

अंततः ब्लॉक को हमेशा निष्पादित किया जाता है, चाहे कोई अपवाद फेंका जाए या नहीं।


11
पहला पैराग्राफ जरूरी नहीं कि सच हो। कोशिश करें ब्लॉक को नस्ट किया जा सके। अनियंत्रित अपवाद, अनियंत्रित या नहीं, विधि से बाहर हो जाएगा।
एंडी थॉमस

4
कोशिश करें कि ब्लॉक को नस्ट किया जा सके, लेकिन मैं इसकी सिफारिश नहीं करूंगा। मैं उस तरह से कोड नहीं लिखता।
duffymo

2
@duffymo: "विधि से बुदबुदाती" का क्या अर्थ है?
टुडेबिल्ड

5
@ और "कुछ हद तक एक अपवाद" के लिए केवल कुछ गैर-तकनीकी भाषा।
duffymo

2
नजरअंदाज नहीं किया; विधि श्रृंखला पास करें।
duffymo

93

पर एक छोटा नोट try/ finally: अंत में हमेशा निष्पादित होगा जब तक

  • System.exit() कहा जाता है।
  • JVM क्रैश हो जाता है।
  • try{}ब्लॉक कभी नहीं समाप्त होता है (उदाहरण के लिए अंतहीन लूप)।

4
किस बारे में try{..} catch{ throw ..} finally{..}? मुझे लगता है कि अंत में निष्पादित नहीं किया जाएगा
sbeliakov

10
उस मामले में अंत में अभी भी बुलाया जाएगा। केवल मूल अपवाद खो गया है।
पीटर लॉरी

यदि आप System.exit () से पहले कॉल करते हैं तो अंत में भी निष्पादित नहीं किया जाएगा।
मिमीरोर

2
@jyw का मतलब है कि ऊपर की सूची में पहले आइटम से मेरा मतलब है।
पीटर लॉरी

मुझे कहना है, यह सभी ठिकानों को कवर करता है!
ऑस्कर ब्रावो

39

जावा लैंग्वेज स्पेसिफिकेशन (1) बताता है कि कैसे try-catch-finallyनिष्पादित किया जाता है। कोई भी कैच न होना किसी दिए गए थ्रोएबल को पकड़ने में सक्षम न होने के बराबर है।

  • यदि मान V को फेंकने के कारण ट्राई ब्लॉक का निष्पादन अचानक पूरा हो जाता है, तो एक विकल्प है:
    • यदि रन-टाइम प्रकार V प्रयास विवरण के किसी भी पकड़ खंड के पैरामीटर के लिए असाइन किया गया है, तो
      ……
    • यदि रन-टाइम प्रकार का V, कोशिश स्टेटमेंट के किसी भी कैच क्लॉज के पैरामीटर के लिए असाइन नहीं किया जाता है, तो अंत में ब्लॉक निष्पादित किया जाता है । फिर एक विकल्प है:
      • यदि अंत में ब्लॉक सामान्य रूप से पूरा हो जाता है, तो मूल्य वी के एक फेंक के कारण प्रयास विवरण अचानक पूरा हो जाता है।
      • यदि अंत में कारण S के लिए अचानक पूरा हो जाता है, तो कारण S के लिए अचानक प्रयास पूर्ण हो जाता है (और मान V का फेंक छोड़ दिया जाता है और भुला दिया जाता है)।

(१) प्रयत्न-अंत में पकड़ना


16

बाहरी ब्लॉक को अपवाद फेंकने से पहले आंतरिक अंत में निष्पादित किया जाता है।

public class TryCatchFinally {

  public static void main(String[] args) throws Exception {

    try{
        System.out.println('A');
        try{
            System.out.println('B');
            throw new Exception("threw exception in B");
        }
        finally
        {
            System.out.println('X');
        }
        //any code here in the first try block 
        //is unreachable if an exception occurs in the second try block
    }
    catch(Exception e)
    {
        System.out.println('Y');
    }
    finally
    {
        System.out.println('Z');
    }
  }
}

का परिणाम

A
B
X
Y
Z

6

अंततः ब्लॉक हमेशा कोशिश ब्लॉक के समाप्त होने के बाद चलाया जाता है, चाहे कोशिश सामान्य रूप से समाप्त हो या असामान्य रूप से अपवाद, एर, फेंकने योग्य के कारण।

यदि किसी अपवाद को कोड ब्लॉक के भीतर किसी भी कोड द्वारा फेंक दिया जाता है, तो वर्तमान विधि केवल उसी अपवाद को फिर से फेंकता है (या फेंकना जारी रखता है) (अंत में ब्लॉक चलाने के बाद)।

यदि अंत में ब्लॉक अपवाद / त्रुटि / फेंकने योग्य है, और पहले से ही एक फेंकने योग्य है, तो यह बदसूरत हो जाता है। काफी स्पष्ट रूप से, मैं वास्तव में क्या होता है (मेरे प्रमाणीकरण वर्षों के लिए इतना कुछ) भूल जाते हैं। मुझे लगता है कि दोनों थ्रैबल्स एक साथ जुड़े हुए हैं, लेकिन कुछ विशेष वूडू है जो आपको करना है (यानी - "अंतिम रूप से" बारफेड, एर, थ्रो से पहले मूल समस्या को प्राप्त करने के लिए एक विधि कॉल मुझे देखना होगा)।

संयोग से, संसाधन प्रबंधन के लिए प्रयास करना / अंत में एक बहुत ही सामान्य बात है, क्योंकि जावा में कोई विध्वंसक नहीं है।

जैसे -

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

"अंत में", एक और टिप: आप अगर है एक पकड़ने में डालने के लिए परेशान है, या तो पकड़ विशिष्ट (उम्मीद) फेंकने योग्य उपवर्गों, या बस पकड़ "फेंकने योग्य", नहीं "अपवाद", एक सामान्य कैच-ऑल त्रुटि जाल के लिए। बहुत सारी समस्याएं, जैसे प्रतिबिंब नासमझ, "अपवाद" के बजाय "त्रुटियां" फेंक देते हैं, और जो किसी भी "कैच ऑल" कोडेड के रूप में सही से फिसल जाएंगे:

catch ( Exception e) ...  // doesn't really catch *all*, eh?

इसके बजाय यह करें:

catch ( Throwable t) ...

बदसूरत भाग के लिए नीचे कार्लोस हेबर्गर द्वारा उत्तर देखें।
मध्याह्न

3

संस्करण 7 से पहले जावा संस्करण कोशिश-कैच के इन तीन संयोजनों के लिए अनुमति देते हैं ...

try - catch
try - catch - finally
try - finally

finallyब्लॉक को हमेशा try/ या catchब्लॉक में चल रहे किसी भी मामले का निष्पादन नहीं किया जाएगा । इसलिए यदि कोई catchब्लॉक नहीं है, तो अपवाद यहां संभाला नहीं जाएगा।

हालाँकि, आपको अभी भी अपने कोड में कहीं अपवाद हैंडलर की आवश्यकता होगी - जब तक कि आप अपने आवेदन को पूरी तरह से क्रैश नहीं करना चाहते। यह आपके एप्लिकेशन की वास्तुकला पर निर्भर करता है कि वह हैंडलर कहां है।

  • जावा कोशिश ब्लॉक को या तो पकड़ या अंत में ब्लॉक करना चाहिए।
  • प्रत्येक कोशिश ब्लॉक के लिए शून्य या अधिक कैच ब्लॉक हो सकते हैं, लेकिन केवल एक अंत में ब्लॉक।
  • यदि प्रोग्राम से बाहर निकलता है (सिस्टम System.exit () कॉल करके या एक घातक त्रुटि पैदा कर सकता है जो प्रक्रिया को समाप्त करने का कारण बनता है) तो अंततः ब्लॉक को निष्पादित नहीं किया जाएगा।

1
"संस्करण 7 से पहले अनुमति दें" क्या आप अनुमान लगा रहे हैं कि जावा 7 और जावा 8 इन तीन संयोजनों की अनुमति नहीं देते हैं? मुझे संदेह है कि आपका क्या मतलब है, लेकिन यही आपका जवाब है।
लादुविज्क

क्या अंतत: ब्लॉक को क्रियान्वित किया जाता है अगर कोशिश ब्लॉक में रिटर्न स्टेटमेंट है?
राहुल यादव

@ राहुल हां, आखिरकार कहा जाएगा। Ref: stackoverflow.com/questions/65035/…
roottraveller

1
@Aaron - कोशिश-के-संसाधन के लिए नया वाक्यविन्यास, जो स्वचालित रूप से कॉल करता है .close () कोशिश कीवर्ड के बाद परेंस के भीतर निर्मित किसी भी चीज़ पर।
रोबोप्रोग

2

अगर यह एक अपवाद या फेंकने योग्य कुछ का सामना करता है तो प्रयास ब्लॉक कैसे काम करता है

अपवाद को ब्लॉक से बाहर फेंक दिया जाता है, जैसे किसी अन्य मामले में जहां इसे पकड़ा नहीं गया है।

अंत में ब्लॉक को निष्पादित किया जाता है, भले ही कोशिश ब्लॉक से बाहर कैसे निकले - भले ही कोई भी कैच हो, चाहे मैचिंग कैच हो।

पकड़ ब्लॉक और अंत में कोशिश ब्लॉक के ऑर्थोगोनल भाग हैं। आपके पास या दोनों हो सकते हैं। जावा 7 के साथ, आप न तो कर पाएंगे!


1

क्या आप इसे उस कार्यक्रम के साथ नहीं आजमाते हैं? यह आखिरकार ब्लॉक करेगा और अंत में ब्लॉक को निष्पादित करेगा, लेकिन, अपवाद को नियंत्रित नहीं किया जाएगा। लेकिन, अंत में ब्लॉक में उस अपवाद को खारिज किया जा सकता है!


1

अंतत: ब्लॉक को ब्लॉक ब्लॉक पूरा होने के बाद निष्पादित किया जाता है। यदि अंत में ब्लॉक को छोड़ दिया जाता है तो कुछ को ब्लॉक के अंदर फेंक दिया जाता है।


0

tryब्लॉक के अंदर हम ऐसे कोड लिखते हैं जो एक अपवाद को फेंक सकते हैं। catchखंड है, जहां हम अपवाद संभाल। finallyब्लॉक हमेशा कोई बात नहीं अपवाद होता है या नहीं मार डाला जाता है।

अब यदि हमारे पास ट्राइ-कैच-अंततः ब्लॉक के बजाय ट्राइ-अंततः ब्लॉक है तो अपवाद को नहीं संभाला जाएगा और ट्रायल ब्लॉक के बजाय कंट्रोल ब्लॉक को पकड़ने के लिए जाने के बाद अंत में ब्लॉक में जाएगा। जब हम अपवाद के साथ कुछ नहीं करना चाहते हैं तो हम कोशिश-अंत में ब्लॉक का उपयोग कर सकते हैं।


0

tryब्लॉक में फेंके जाने या न दिए जाने के बावजूद, finallyब्लॉक निष्पादित किया जाएगा। अपवाद नहीं पकड़ा जाएगा।

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