2012-04-24 18 views
5

यह प्रोग्राम आउटपुट के रूप में 6 देता है, लेकिन जब मैं लाइन 9 को अपूर्ण करता हूं, आउटपुट 5 है। क्यों? मुझे लगता है कि बी को नहीं बदला जाना चाहिए, मुख्य में 5 रहना चाहिए।मूल्य/संदर्भ से गुजरता है, क्या?

1 class C1{ 
2  int a=5; 

3  public static void main(String args[]){ 
4   C1 b=new C1(); 
5   m1(b); 
6   System.out.println(b.a); 
7  } 

8  static void m1(C1 c){ 
9   //c=new C1(); 
10   c.a=6; 
11 } 
12 } 
+10

जावा * हमेशा * मूल्य से गुजरता है, लेकिन आपके द्वारा गुजरने वाला मान संदर्भ चर है, इसलिए यह * इस स्थिति में संदर्भ द्वारा पारित होने लगता है (लेकिन यह नहीं है)। संपादित करें, जैसा कि @mprabhat अपने महान उत्तर (1+) में बताता है। इसके अलावा मैंने आपके प्रश्न को उखाड़ फेंक दिया क्योंकि मुझे नहीं लगता कि यह क्यों कम हो गया था। क्या हम डाउनवोटिंग कर रहे हैं क्योंकि लोग जावा को जानकर पैदा नहीं हुए हैं? –

+1

आपको डीबगर में अपने कोड के दोनों संस्करणों के माध्यम से कदम उठाना चाहिए और अंतर देखें। –

+1

//s.a http://stackoverflow.com/questions/40480/is-java-pass-by-reference – FailedDev

उत्तर

10

जब आप जावा में वस्तु पारित वे विधि m1 में main विधि और c तर्क के रूप में में b द्वारा संदर्भित संदर्भ अर्थ वस्तु के रूप में पारित कर रहे हैं, वे एक ही वस्तु है, इसलिए जब आप से 6 मान बदलने के लिए दोनों बिंदु यह main विधि में परिलक्षित होता है।

अब जब आप तो c = new C1(); करने की कोशिश आप एक अलग वस्तु को इंगित करने के c लेकिन b बनाया अभी भी वस्तु जो आप अपने main विधि में बनाया की ओर इशारा करते है इसलिए अद्यतन मूल्य 6 मुख्य विधि में दिखाई नहीं देता है और आपको मिल 5.

+3

यहां एक बहुत अच्छा लेख है जो बताता है कि @mprabhat चित्रों के साथ क्या कह रहा है अगर इससे आपकी मदद मिलती है। http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html – Windle

+0

@ विंडल बहुत अच्छा लेख +1 – mprabhat

+0

यहां मुझे संदेह है, 'संदर्भ संदर्भ द्वारा पारित किए जाते हैं', यह कथन पूरी तरह गलत है, जावा में आईएमएचओ, इसके बजाय 'ऑब्जेक्ट रेफरेंस वैल्यू' द्वारा पारित किया गया है, मैं इसके लिए एक अद्भुत उदाहरण दे सकता हूं, हालांकि किताबें अन्यथा कहती हैं :-) +1, हालांकि शेष भाग –

3

आप अपनी विधि m1 को किसी प्रकार के प्रकार के संदर्भ के संदर्भ में कॉपी कर रहे हैं।

यदि आप लाइन को असम्बद्ध करते हैं, तो आप उस संदर्भ को ले रहे हैं और इसे कहीं और इंगित कर रहे हैं (यह नहीं कि मूल संदर्भ अभी भी पहली वस्तु पर इंगित कर रहा है), इसलिए, जब आप बी के मान को मुद्रित करते हैं, तो आप प्रिंट कर रहे हैं मूल वस्तु का मूल्य, जिसे आपने नहीं बदला है।

इस प्रश्न के कुछ अच्छे जवाब हैं, और आपको इसे वास्तव में देखना चाहिए।

Is Java "pass-by-reference" or "pass-by-value"?

+1

धन्यवाद, मुझे अभी भी लगता है मेरे सिर में पॉइंटर्स के मामले में थोड़ा सा (यह मूल रूप से वे सार में हैं), लेकिन संदर्भ सही शब्दावली है। – pcalcao

1

इस वजह एम 1 में सी (C1 ग) एक वस्तु के लिए एक संदर्भ है, और जब आप अब c.a = 6 करना एक है इस वस्तु में 6 के बराबर है। लेकिन अगर आप इस विधि के अंदर c = new c1() करते हैं, तो सी अब पूरी तरह से नई ऑब्जेक्ट का संदर्भ दे रहा है, तो आप इस नई ऑब्जेक्ट में c.a = 6 कर रहे हैं। बाद में, आप विधि से बाहर निकलते हैं, और अन्य सी ऑब्जेक्ट में अभी भी मूल्य 5

1

आपकी विधि m1(b); मुख्य में कॉल की जाती है, जिसके कारण एम 1 में एक नया उदाहरण बनाया गया है जो मुख्य विधि में पहले से ही सी 1 का उदाहरण बना देता है। यदि आप एम 1 में तत्कालता पर टिप्पणी करते हैं, तो मुख्य में पहला उदाहरण प्रभावी होता है। ऐसा इसलिए है क्योंकि जावा वस्तुओं में संदर्भ द्वारा संदर्भित नहीं किया जाता है।

3

जावा पास-बाय-वैल्यू है, लेमन शब्दों में जिसका अर्थ है कि जब आप कोई तर्क देते हैं तो आप पॉइंटर परिवर्तनीय की एक प्रति बनाते हैं। ऑब्जेक्ट वैरिएबल को वास्तव में सी में पॉइंटर्स की तरह पढ़ा जाना चाहिए: यह किसी भी तरह से चीजों को समझने में आसान बनाता है, कम से कम जब सी दुनिया से आ रहा है (जहां सी केवल पास-दर-मूल्य है)।

तो जब c=new C1(), या सामान्य रूप में कर रही है जब c के लिए किसी भी काम के प्रदर्शन, आप c किसी अन्य स्थान को इंगित (जो पूर्व में स्मृति कि b उठाई का एक ही स्थान की ओर इशारा) कर रहे हैं। इसलिए c.a=6c द्वारा इंगित ऑब्जेक्ट के सदस्य को असाइनमेंट है, जो ऑब्जेक्ट b द्वारा इंगित नहीं है।

1

जावा में आदिम प्रकारों के अलावा सब कुछ संदर्भ द्वारा पास किया जाता है, हालांकि यह संदर्भ की प्रति को पास करता है।

इसलिए पहले मामले में आपके मामले में दोनों पॉइंटर्स बी और सी एक ही ऑब्जेक्ट को इंगित करते हैं इसलिए अद्यतन मूल्य मुख्य विधि में वापस दिखाई देता है।

दूसरे उदाहरण में जब आप एक नई वस्तु (नए कॉल करके) को इंगित करने के लिए सी बनाते हैं तो बी मुख्य विधि में बनाए गए ऑब्जेक्ट को इंगित कर रहा है इसलिए अद्यतन मूल्य मुख्य विधि में प्रतिबिंबित नहीं होता है क्योंकि बी और सी दो को इंगित कर रहे हैं विभिन्न वस्तुओं।

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

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