2013-08-04 9 views
6

क्यों StringBuilder मुद्रित नहीं पड़ता कि यह एक छोटे से कोडस्ट्रिंगबिल्डर क्यों प्रिंट नहीं करता है?

public final class Test1 { 

    public void test() { 
     System.out.println(setFin().toString()); 
    } 

    protected StringBuilder setFin() { 
     StringBuilder builder = new StringBuilder(); 
     try { 
      builder.append("John"); 
      return builder.append("Ibrahim"); 
     } finally { 
      System.out.println("In finaly"); // builder.append("-DarElBeida"); 
      builder = null; 
     } 
    }  

    public static void main(String args[]){ 
     new Test1().test(); 
    } 
} 

में मुद्रित करना चाहिए पिछले बयान setFin() में मार डाला (finally ब्लॉक में) में मैं builder को null सौंपा है, लेकिन मेरे कोड प्रिंट "In finally" और फिर "JohnIbrahim" । क्या कोई मुझे बता सकता है कि यहां क्या हो रहा है?

+1

यह अत्याचारी कोड है। शायद, आप बस http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html – nes1983

उत्तर

5

जब try ब्लॉक के अंदर कोई कथन है, तो यह वास्तव में लौटने से पहले finally ब्लॉक निष्पादित करेगा।

और विधि वापस नहीं करता है null क्योंकि return बयान वास्तविक StringBuilder वस्तु के लिए एक संदर्भ, चर builder के लिए नहीं रखती है।

स्थापना builder == null ही StringBuilder को नहीं हटाता है, यह सिर्फ यह करने के लिए builder के संदर्भ चला जाता है।

यह व्यवहार भ्रमित हो सकता है। बातें स्पष्ट करना करने के लिए यह ट्राई/कैच/अंत में ब्लॉक के बाहर से वापस जाने के लिए उपयोगी हो सकता है:

StringBuilder builder = new StringBuilder(); 

try { 
    builder.append("John"); 
    builder.append("Ibrahim"); 
} finally { 
    System.out.println("In finaly"); // builder.append("-DarElBeida"); 
    builder = null; 
} 

return builder; 
+1

पढ़ना चाहते हैं, मुझे लगता है कि ओपी भ्रमित है कि यह क्यों 'शून्य' प्रिंट नहीं कर रहा है। –

+0

नहीं, वह उम्मीद करता है कि यह बिना "अंत में" नाम मुद्रित करेगा। – duffymo

+0

मुझे लगता है कि भ्रम इस बारे में है कि यह 'शून्य' क्यों प्रिंट नहीं कर रहा है (जो आपका कथन वास्तव में समझा नहीं जाता है - यह 'बिल्डर = नल'' वापसी से पहले मूल्यांकन किया जाता है "तो इसे" शून्य वापस करना चाहिए ") – Mat

3

आप builder लौट रहे हैं। इसके बाद आप builder को शून्य पर सेट करें। लेकिन यह पहले से ही वापस कर दिया गया है। इससे कोई फर्क नहीं पड़ता कि आप चर के बाद क्या करते हैं। वापसी मूल्य पहले से ही "लॉक-इन" है। आप जो कर सकते हैं वह उस वस्तु के साथ गड़बड़ है जो वापस किया जा रहा है। उदाहरण के लिए, builder.setLength(0) इसमें सभी टेक्स्ट हटा देंगे।

सिद्धांत रूप में, आप अंत में ब्लॉक से return null भी कर सकते हैं, लेकिन वह (वापसी मूल्य बदलना) अत्यधिक निराश है।

3

वापसी मूल्य का मूल्यांकन किया और ढेर पर संग्रहीत, finally ब्लॉक रन से पहले किया गया है। ध्यान दें कि ढेर पर मूल्य वास्तव में StringBuilder संदर्भ का मान है। इसलिए, भले ही आप builder से null सेट करें, यह पहले से ही स्टैक पर मूल्यांकन किए गए return मान को परिवर्तित नहीं करता है। हालांकि, यदि वापसी मान एक म्यूटेबल ऑब्जेक्ट का संदर्भ है, तो आप ऑब्जेक्ट को म्यूट कर सकते हैं, और परिवर्तन return मान में दिखाई देंगे।

उदा लिए

, अगर आप नीचे दिए बयान finally ब्लॉक में बजाय nullifying के संदर्भ जोड़ें:

builder.append("Hrithik Roshan"); 

तो आप वापसी मान में है कि सामग्री दिखाई दे।

हालांकि, अगर आप returnbuilder फिर, finally ब्लॉक से, यह पिछले का मूल्यांकन return बयान overright होगा। लेकिन ध्यान रखें कि यह एक अच्छा विचार नहीं है।

2

finally हमेशा निष्पादित होता है, जब तक कि JVM क्रैश या try ब्लॉक खत्म होने से पहले बाहर निकलता है।

try ब्लॉक एक return बयान की वजह से पूर्ण करता है, return की अभिव्यक्ति से पहलेfinally ब्लॉक कार्यान्वित एकल मान में मूल्यांकन किया जाता है। वह मान सहेजा गया है, और finally ब्लॉक पूर्ण होने पर लौटा दिया गया है।

इस प्रकार, builder = null के असाइनमेंट का कोई प्रभाव नहीं पड़ता है क्योंकि builder.append("Ibrahim") का मूल्यांकन पहले ही finally निष्पादन के समय समाप्त हो चुका है।

1

builder आपके द्वारा बनाए गए स्ट्रिंगबिल्डर का संदर्भ रखता है। जब आप builder = null करते हैं, तो आप उस संदर्भ को पकड़ने के लिए builder सेट कर रहे हैं। स्ट्रिंगबिल्डर स्वयं भी मौजूद है (कम से कम कचरा संग्रह होने तक)।

क्या हो रहा है यह है कि आपका return कथन स्ट्रिंगबिल्डर के संदर्भ को वापस कर रहा है। यह नहीं परिवर्तनीय builder लौटा रहा है; यह उस चीज़ का संदर्भ लौटा रहा है जो builder को संदर्भित करता है। तो भले ही आप चर को मिटा रहे हों, रिटर्न स्टेटमेंट में पहले से बनाए गए ऑब्जेक्ट का संदर्भ है।

यदि आपने अपने finally ब्लॉक में builder मुद्रित किया है, तो यह वहां शून्य होगा।

0

पहले return कथन निष्पादित किया गया जो builder.append("Ibrahim") निष्पादित करता है जो StringBuilder का संदर्भ देता है। जनमत ढेर में बचाया जाता है। फिर finally ब्लॉक को उत्साहित किया। आपने स्थानीय चर को खाली कर दिया है, लेकिन विधि वास्तव में वापस आने के बाद StringBuilder ऑब्जेक्ट का संदर्भ कॉलर को पास कर दिया गया है। यही कारण है कि सभी मूल्य मुद्रित। त्रुटि यह है कि आप builder को finally ब्लॉक में कोई मान निर्दिष्ट नहीं करते हैं जिसका उपयोग कभी नहीं किया जाता है। स्टैक return कथन ऑपरेंड के मान को वास्तव में लौटने से पहले रखता है, यानी finally ब्लॉक के बाद। यदि आप विधि से संदर्भ वापस नहीं करना चाहते हैं तो आपको finally ब्लॉक में return null होना चाहिए, जो स्टैक में मान को ओवरराइड करेगा।

} finally { 
    System.out.println("In finaly"); // builder.append("-DarElBeida"); 
    return null; 

} 
संबंधित मुद्दे