2012-07-11 7 views
6

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

आप कृपया मेरी मदद कर सकते ...

+8

पहले प्रश्न का आपका उत्तर गलत है। संकलक यह नहीं सोचने वाला है कि कोई 'पकड़' ब्लॉक नहीं है। यह स्पष्ट रूप से अभी भी आपके कोड में है, और तथ्य यह है कि 'आखिरकार' ब्लॉक संकलन-समय त्रुटि के कारण सही होगा। – BoltClock

+0

बोल्टक्लॉक सही है - आपको अपने पहले प्रश्न पर एक कंपाइलर त्रुटि मिलती है। * पकड़ * तुरंत * * कोशिश * – StuartLC

+1

द्वारा किया जाना चाहिए कैच ब्लॉक सिंकैक्टिक रूप से प्रयास ब्लॉक के तुरंत बाद होना चाहिए। कोई अन्य कारण नहीं। – Sabbath

उत्तर

4

खैर यह कुछ इस तरह का मतलब होगा:

try 
{ 
    somCode(); 
} 
someMoreCode(); 
catch 
{ 
} 

इसका क्या मतलब चाहिए? यह संभव नहीं है क्योंकि इसका कोई अर्थपूर्ण नहीं है, और इसलिए भाषा डिजाइनरों द्वारा वाक्य रचनात्मक रूप से गलत होने का निर्णय लिया गया है!

+1

हां यह है ... एक छोटा सा, एक छोटा सा थैंट तुम्हारा सच है, लेकिन यह है। मैंने जो कहा वह पूरी तरह से सही है: इसका संकलन नहीं किया जा सकता क्योंकि संकलक कारण जावा डिजाइनरों ने फैसला किया कि इसका कोई मतलब नहीं होगा, इसलिए इसे वाक्यविन्यास द्वारा प्रतिबंधित किया गया है। ठीक है जैसे मैंने कहा "कार टर्की एक खाती है": इसमें कोई अर्थशास्त्र नहीं है और इसलिए इसे वाक्यविन्यास – Kek

0

कोशिश और की तरह पकड़ .. अगर और कुछ .. तो वहाँ ट्राई एवं कैच ब्लॉक के बीच कोड जोड़ने के लिए कोई जरूरत नहीं है

11

ठीक है, पहले सबसे पहले - कंपाइलर कोड निष्पादित नहीं करता है, यह बस इसे संकलित करता है, इसे JVM द्वारा चलाया जा सकता है।

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

आइए मान इस वैध जावा है (इस संकलन नहीं करता है):

try { 
    throw new Exception(); 
} 
System.out.println("Sup!"); 
catch(Exception e) { } 

जब अपवाद फेंक दिया जाता है, कि लाइन है कि बाहर प्रिंट Sup! अभी भी छोड़ दिया हो जाएगा के रूप में JVM खोज कर रहा है Exception के इलाज के लिए उपयुक्त अपवाद हैंडलर पर कूदने के लिए। तो, एक तरह से, कोड व्यवहार करता है जैसे कि यह कोशिश करता था {} खुद को ब्लॉक करें, यही कारण है कि यह वास्तव में कोई फर्क नहीं पड़ता कि यह कहां है, और जावा निर्दिष्ट करता है कि यह (अब बेकार साबित हुआ) निर्माण अवैध है।

अब क्या होगा यदि कोशिश के बाद वह कोड एक और अपवाद फेंकना था? यदि यह वैध कोड था, तो यह एक नेस्टेड प्रयास की तरह व्यवहार करेगा ... मूल प्रयास ब्लॉक में ब्लॉक को पकड़ें। बेशक, एक बार चीजें जटिल होने लगती हैं, जिस दृष्टिकोण से प्रयास और पकड़ने के बीच कोई स्पष्ट कनेक्शन नहीं है, वह अस्पष्ट हो सकता है, और जेवीएम यह नहीं जान पाएगा कि कौन सा पकड़/आखिरकार ब्लॉक है (विशेष रूप से हैंडलर के बाद से एक ही समारोह में, या यहां तक ​​कि एक ही पैकेज में नहीं होना चाहिए!)।

+0

द्वारा अब तक का सबसे अच्छा जवाब दिया गया है! (+1) – alfasin

+0

धन्यवाद! कुछ और छोटी चीजें (विशेष रूप से मेरे छोटे जावा स्निपेट की गलती के बारे में एक स्पष्ट बयान) जोड़ा गया –

+1

जेवीएम स्तर पर ध्यान दें कि ब्लॉकों को नेस्टेड करने की कोई आवश्यकता नहीं है। आपके पास 'foo() हो सकता है; बार(); बाज़(); ', और दोनों' foo() 'और 'baz()' पकड़ अपवाद हैं और _same_ पकड़ कोड पर जाएं, जबकि 'बार()' एक अलग हो जाता है। जो कुछ भी होता है वह एक सारणी दिखाती है जिसमें बाइटकोड श्रेणियां होती हैं जो पकड़ने वाले हैंडलर पर जाती हैं; संकलक इस तालिका को किसी भी तरह से स्थापित कर सकता है। इसलिए जब इस तरह का निर्माण 'जावैक' को भ्रमित कर सकता है, तो JVM आपके द्वारा परिभाषित किए गए जो भी अर्थशास्त्र को लागू करने में प्रसन्न है। – bdonlan

4

खैर, झुकाव का जवाब यह है कि भाषा का नमूना इसे मना करता है।

लेकिन चलिए थोड़ा सा कदम उठाएं और इसके बारे में सोचें - क्या होगा यदि आप कर सकते हैं?

try { 
    foo(); 
} 
bar(); 
catch (Exception e) { 
    baz(); 
} 

इस के अर्थशास्त्र क्या हो सकता है? अगर हम foo() में अपवाद प्राप्त करते हैं, तो baz() कहा जाता है? bar() के बारे में क्या?यदि bar() फेंकता है, तो क्या हम उस मामले में अपवाद पकड़ते हैं?

try { 
    foo(); 
} catch (Exception e) { 
    baz(); 
} 
bar(); 

bar()में अपवाद पकड़ा कर रहे हैं, और foo() में अपवाद:

हैं bar() में अपवाद पकड़े नहीं हैं, और foo() में अपवाद चलने से bar() रोकने के लिए, तो निर्माण बराबर करने के लिए है bar() को चलने से रोकें, फिर निर्माण के बराबर है:

try { 
    foo(); 
    bar(); 
} catch (Exception e) { 
    baz(); 
} 
foo() में

bar() में अपवाद पकड़ा नहीं हैं, और अपवाद नहीं चलने से bar() रोकने (bar() हमेशा निष्पादित किया जाता है) करते हैं, तो निर्माण के बराबर है:

try { 
    foo(); 
} catch (Exception e) { 
    baz(); 
} finally { 
    bar(); 
} 

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

एक अलग रूप में, एक संभावित कारण है कि हम ऐसा नहीं कर सकते हैं:

try { 
    foo(); 
} finally { 
    bar(); 
} catch (Exception e) { 
    baz(); 
} 

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