2012-08-03 24 views
7

शुरुआती जावा सवाल के बाद परिवर्तन नहीं करता है, लेकिन मैं नहीं समझ सकता कैसे फोन-दर-मूल्य (या संदर्भ) नीचे दिए गए उदाहरण में काम कर रहा है -जावा - वस्तु राज्य विधि कॉल

कैसे आ स्ट्रिंग मान संशोधित नहीं है मेरे कस्टम स्ट्रिंग ऑब्जेक्ट के दौरान यह विधि से बाहर निकलने के बाद। ? दिनांक की तरह अन्य वर्गों के साथ एक ही ..

public class StringMadness { 

public static void main(String[] args) { 
    String s = "Native String"; 
    CustomStringObject cs = new CustomStringObject(); 
    System.out.println("Custom String Before: " + cs.str); 
    hello(cs); 
    System.out.println("Custom String After: " + cs.str); 

    System.out.println("Native String Before: " + s); 
    hello(s); 
    System.out.println("Native String After: " + s); 
} 

private static void hello(String t) { 
    t = "hello " + t; 
} 

private static void hello(CustomStringObject o) { 
    o.str = "hello " + o.str; 
    } 
} 

class CustomStringObject { 

String str = "Custom String"; 
} 

उत्तर

16

इन दोनों तरीकों की तुलना करें:

private static void hello(String t) { 
    t = "hello " + t; 
} 

private static void hello(CustomStringObject o) { 
    o.str = "hello " + o.str; 
} 

पहले मामले में, आप बताए रहे हैं t पर नया मान। इसका कॉलिंग कोड पर कोई प्रभाव नहीं पड़ेगा - आप केवल पैरामीटर के मान को बदल रहे हैं, और सभी तर्क जावा में मान द्वारा पारित किए जाते हैं।

दूसरे मामले में, आप o.str के लिए एक नया मान निर्दिष्ट कर रहे हैं। यह ऑब्जेक्ट के भीतर फ़ील्ड का मान बदल रहा है कि o का मान संदर्भित करता है। कॉलर उस परिवर्तन को देखेगा, क्योंकि कॉलर के पास अभी भी उस ऑब्जेक्ट का संदर्भ है।

संक्षेप में: जावा हमेशा मूल्य द्वारा पारित का उपयोग करता है, लेकिन आप याद करने के लिए है कि कक्षाओं के लिए, एक चर (या वास्तव में किसी भी अन्य अभिव्यक्ति) के मूल्य के लिए एक संदर्भ, नहीं एक वस्तु है की जरूरत है। आप पैरामीटर गुजर उपयोग करने के लिए देखने की जरूरत नहीं है इस:

Foo foo1 = new Foo(); 
Foo foo2 = foo1; 
foo1.someField = "changed"; 
System.out.println(foo2.someField) // "changed" 

यहाँ दूसरी पंक्ति प्रतियां foo2 में foo1 का मूल्य - दो चर एक ही वस्तु को देखें, तो यह कोई फर्क नहीं पड़ता है जो आप चर इसका उपयोग करने के लिए उपयोग करें।

+0

आह .. मैं इसे देखता हूं। धन्यवाद .... मूल रूप से, मेरा 'हैलो (कस्टमस्ट्रिंग ऑब्जेक्ट ओ) 'ओ = नया कस्टमस्ट्रिंग ऑब्जेक्ट()' के रूप में एक नया उदाहरण तत्काल था और मैंने हैलो विधि के बाहर देखा, इंस्टेनेशन का कोई प्रभाव नहीं पड़ा। इस सवाल को ट्रिगर किया गया है। –

+0

@ जोन नाइस स्पष्टीकरण। फू उदाहरण मदद करता है। +1 –

+0

यदि कॉलर शून्य संदर्भ पास करता है तो मैंने देखा है कि कॉलली संशोधन कॉलर को प्रतिबिंबित नहीं करता है। ऐसा क्यों है? –

0

t नई वस्तु को इंगित और केवल विधि के दायरे वाला होगा, इसलिए परिवर्तन नहीं बाहर से दिखाई दे।

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

+0

यह वास्तव में नहीं है क्योंकि तार अपरिवर्तनीय हैं रहा है। भले ही यह एक स्ट्रिंगबिल्डर था, पैरामीटर के लिए एक नया मान निर्दिष्ट करने से कॉलर प्रभावित नहीं होगा ... –

+0

@ जोनस्केट: सहमत हैं। मेरा जवाब अपडेट किया गया। – kosa

4

वहाँ दो तरीकों के बीच एक महत्वपूर्ण अंतर है: hello(String) का उपयोग कर आप String को संदर्भ बदलने के लिए कोशिश कर रहे हैं, और hello(CustomObject), एक संदर्भ दिया साथ, आप संदर्भ का उपयोग कर रहे वस्तु के एक सदस्य को बदलने के लिए ।

hello(String) एक String के लिए एक संदर्भ लेता है। फ़ंक्शन में आप संदर्भित करने वाली ऑब्जेक्ट को बदलने की कोशिश कर रहे हैं, लेकिन आप संदर्भ के पास-बाय-वैल्यू प्रति को बदल रहे हैं। तो आपके परिवर्तन विधि के बाहर परिलक्षित नहीं होते हैं।

hello(CustomObject) एक वस्तु है जिसे आप वास्तविक वस्तु को बदलने के लिए उपयोग कर सकते हैं के लिए एक संदर्भ की एक प्रति दी गई है। ऑब्जेक्ट के सामग्री को बदलने के रूप में इसके बारे में सोचें। तो आपके परिवर्तन कॉलर में परिलक्षित होते हैं।

एक संदर्भ एक वस्तु को देखते हुए, आप वस्तु यह उजागर तरीकों का उपयोग कर/बदल सकते हैं क्षेत्रों

0

क्योंकि स्ट्रिंग के लिए आप बस स्थानीय पैरामीटर संदर्भ बदल रहे हैं।

0

काम नहीं करता क्योंकि स्ट्रिंग अपरिवर्तनीय वस्तु

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