खोज…


टिप्पणियों

इससे आपको "Null Pointer Exception" को समझने में मदद मिलनी चाहिए - एक उन में से एक हो जाता है क्योंकि एक ऑब्जेक्ट संदर्भ शून्य है, लेकिन प्रोग्राम कोड प्रोग्राम को उस ऑब्जेक्ट संदर्भ में कुछ का उपयोग करने की उम्मीद करता है। हालांकि, कि अपने ही विषय के हकदार हैं ...

विधि पैरामीटर के रूप में ऑब्जेक्ट संदर्भ

यह विषय वस्तु संदर्भ की अवधारणा की व्याख्या करता है; यह उन लोगों पर लक्षित है जो जावा में प्रोग्रामिंग के लिए नए हैं। आपको पहले से ही कुछ शर्तों और अर्थों से परिचित होना चाहिए: कक्षा की परिभाषा, मुख्य विधि, वस्तु उदाहरण, और तरीकों की कॉलिंग "एक वस्तु पर", और विधियों को मापदंडों से गुजरना।

public class Person {

  private String name;

  public void setName(String name) { this.name = name; }

  public String getName() { return name; }

  public static void main(String [] arguments) {
    Person person = new Person();
    person.setName("Bob");

    int i = 5;
    setPersonName(person, i);

    System.out.println(person.getName() + " " + i);
  }

  private static void setPersonName(Person person, int num) {
    person.setName("Linda");
    num = 99;
  }
}

जावा प्रोग्रामिंग में पूरी तरह से सक्षम होने के लिए, आपको इस उदाहरण को अपने सिर के ऊपर से किसी और को समझाने में सक्षम होना चाहिए। जावा कैसे काम करता है, इसकी अवधारणाएं मौलिक हैं।

जैसा कि आप देख सकते हैं, हमारे पास एक main जो चर person लिए एक वस्तु का तात्पर्य करता है, और उस ऑब्जेक्ट में name फ़ील्ड को "Bob" पर सेट करने के लिए एक विधि कहता है। फिर यह दूसरी विधि कहता है, और person को दो मापदंडों में से एक के रूप में पारित करता है; अन्य पैरामीटर एक पूर्णांक चर है, जिसे 5 पर सेट किया गया है।

कहा जाता है कि विधि "लिंडा 'को पारित मूल्य पर name मान सेट करता है, और पूर्णांक चर को 99 पर सेट करता है, फिर वापस आ जाता है।

तो क्या छपेगा?

Linda 5

तो person किया गया परिवर्तन main प्रभावी क्यों होता है, लेकिन पूर्णांक में किया गया परिवर्तन नहीं होता है?

जब कॉल किया जाता है, तो मुख्य विधि setPersonName विधि के लिए person लिए एक वस्तु संदर्भ setPersonName करती है; कोई भी परिवर्तन जो setAnotherName को उस ऑब्जेक्ट में बनाता है, उस ऑब्जेक्ट का हिस्सा है, और इसलिए वे परिवर्तन अभी भी उस ऑब्जेक्ट का हिस्सा हैं, जब विधि वापस आती है।

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

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

जावा में, सभी प्राइमिटिव्स मूल्य द्वारा पारित किए जाते हैं। ऑब्जेक्ट्स को संदर्भ द्वारा पास किया जाता है, जिसका अर्थ है कि ऑब्जेक्ट के लिए एक पॉइंटर को किसी भी तरीके के पैरामीटर के रूप में पारित किया जाता है जो उन्हें लेते हैं।

एक कम स्पष्ट बात इसका मतलब है: एक नई वस्तु बनाने और इसे एक पैरामीटर के रूप में वापस करने के लिए एक तथाकथित विधि के लिए संभव नहीं है। विधि द्वारा किसी वस्तु को लौटाने का एकमात्र तरीका है, प्रत्यक्ष या परोक्ष रूप से, विधि कॉल द्वारा, विधि से वापसी मान के रूप में है। आइए पहले देखें कि यह कैसे काम नहीं करेगा, और फिर यह कैसे काम करेगा।

आइए हमारे छोटे उदाहरण में एक और विधि यहाँ जोड़ते हैं:

private static void getAnotherObjectNot(Person person) {
  person = new Person();
  person.setName("George");
}

और, setAnotherName को कॉल के नीचे main में वापस, आइए इस पद्धति पर कॉल करें और एक अन्य प्रिंटलाइन देखें:

getAnotherObjectNot(person);
System.out.println(person.getName());

अब यह कार्यक्रम छपेगा:

Linda 5
Linda

उस वस्तु का क्या हुआ जो जॉर्ज के पास थी? खैर, जो पैरामीटर पारित किया गया था वह लिंडा के लिए एक संकेतक था; जब getAnotherObjectNot विधि ने एक नई वस्तु बनाई, तो उसने जॉर्ज ऑब्जेक्ट के संदर्भ में लिंडा ऑब्जेक्ट के संदर्भ को बदल दिया। लिंडा ऑब्जेक्ट अभी भी मौजूद है (ढेर पर), main विधि अभी भी इसे एक्सेस कर सकती है, लेकिन getAnotherObjectNot विधि इसके बाद कुछ भी नहीं कर पाएगी, क्योंकि इसका कोई संदर्भ नहीं है। ऐसा प्रतीत होता है कि कोड के लेखक ने एक नई वस्तु बनाने और उसे वापस पारित करने के लिए विधि का इरादा किया है, लेकिन यदि ऐसा है, तो यह काम नहीं किया।

यदि वह वही है जो लेखक करना चाहता था, तो उसे विधि से नई बनाई गई वस्तु वापस करनी होगी, कुछ इस तरह:

private static Person getAnotherObject() {
  Person person = new Person();
  person.setName("Mary");
  return person;
}

फिर इसे इस तरह से कॉल करें:

Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());

और अब पूरा कार्यक्रम आउटपुट होगा:

Linda 5
Linda
Mary

यहाँ संपूर्ण कार्यक्रम है, दोनों परिवर्धन के साथ:

public class Person {
  private String name;

  public void setName(String name) { this.name = name; }
  public String getName() { return name; }

  public static void main(String [] arguments) {
    Person person = new Person();
    person.setName("Bob");

    int i = 5;
    setPersonName(person, i);
    System.out.println(person.getName() + " " + i);
    
    getAnotherObjectNot(person);
    System.out.println(person.getName());
    
    Person person;
    person = getAnotherObject();
    System.out.println(person.getName());
  }
  
  private static void setPersonName(Person person, int num) {
    person.setName("Linda");
    num = 99;
  }
  
  private static void getAnotherObjectNot(Person person) {
    person = new Person();
    person.setMyName("George");
  }
  
  private static person getAnotherObject() {
    Person person = new Person();
    person.setMyName("Mary");
    return person;
  }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow