2016-02-01 5 views
6

ओरेकल द्वारा आधिकारिक जावा ट्यूटोरियल से लिया गया, question 2 here (मेरे द्वारा बॉयलरप्लेट) देखें।स्ट्रिंग ऑब्जेक्ट में सरणी तत्व सेट करते समय, तत्व ऑब्जेक्ट का संदर्भ देता है?

public static void main(String[] args) { 

    String[] students = new String[10]; 
    String studentName = "Peter Smith"; 
    students[0] = studentName; 
    studentName = null; 

    System.out.println(students[0]); 

} 

जवाब का कहना है कि studentName कचरा संग्रहण के लिए पात्र सरणी students अभी भी यह संदर्भ देता है के बाद से नहीं है। हालांकि, अंतिम पंक्ति "पीटर स्मिथ" प्रिंट करती है, इसलिए मेरे लिए यह गलत लगता है कि students[0] संदर्भ studentName। क्या कोई इसे समझा सकता है?

+2

क्या आप कह रहे हैं कि आपको लगता है कि प्रिंटिंग कुछ प्रभावित करती है या नहीं, इसका संदर्भ है? यदि 'छात्र [0] '* ने' studentName' को निर्दिष्ट स्ट्रिंग का संदर्भ नहीं दिया है, तो इसे कैसे मुद्रित किया जा रहा है? –

+0

इसका और क्या संदर्भ होगा? – ChiefTwoPencils

+3

'छात्र [0] = studentName' परिवर्तनीय' studentName' का संदर्भ बना रहा है, यह स्ट्रिंग अक्षर "पीटर स्मिथ" के लिए 'छात्र [0]' सेट नहीं कर रहा है। – Taelsin

उत्तर

5

आप संदर्भित चर (studentName और students[0]) को उस ऑब्जेक्ट के साथ भ्रमित कर रहे हैं जो वे संदर्भित करते हैं ("पीटर स्मिथ")। studentName और students[0] दोनों String ऑब्जेक्ट "पीटर स्मिथ" का संदर्भ देते हैं। एक बार उनमें से कोई भी संदर्भ "पीटर स्मिथ" - और यह मानते हुए कि अन्य कोई संदर्भ नहीं हैं - वह वस्तु कचरा संग्रह के लिए योग्य होगी। जब वे दायरे से बाहर निकलते हैं तो संदर्भ खुद दूर जाते हैं।

ट्यूटोरियल को यह गलत लगता है। कोई ऑब्जेक्ट studentName नहीं है। studentName एक चर है कि, एक बिंदु पर, "पीटर स्मिथ" का संदर्भ रखता है और दूसरी ओर null है। इसी तरह, students[0] मेमोरी स्थानों की एक सरणी में एक तत्व है जिसमें "पीटर स्मिथ" (उसी String ऑब्जेक्ट) का संदर्भ है। ट्यूटोरियल वे ऑब्जेक्ट्स के संदर्भ में चर के विचार को भ्रमित करता है।

मैं अनुमान लगा सकता हूं कि वे स्मृति उपयोग के विवरण में जाने से बचने के लिए ऐसा करते हैं। यह एक उन्नत विषय है। लेकिन उनकी व्याख्या आईएमओ इससे अधिक भ्रम का कारण बनती है।

+1

मुझे वास्तव में यह गलत मिला। हालांकि, ट्यूटोरियल उत्तर में कहा गया है कि "ऑब्जेक्ट 'छात्र नाम' योग्य नहीं है क्योंकि 'छात्र [0]' अभी भी इसका संदर्भ देता है।" लेकिन क्या यह गलत नहीं है? क्या 'छात्र [0]' स्ट्रिंग को इंगित नहीं करते हैं "पीटर स्मिथ", और 'छात्रनाम' नहीं? ट्यूटोरियल उत्तर मुझे यह मिश्रण करने के लिए भी लगता है। – cmeeren

+0

मैं उलझन में आपको दोषी नहीं ठहराता हूं। उस प्रश्न का उत्तर (ओरेकल ट्यूटोरियल # 2) खराब शब्द है। –

+0

मैंने अपनी टिप्पणी संपादित की, अभी भी उलझन में, क्षमा करें – cmeeren

7

मैं चरण-दर-चरण आरेखों की सहायता से समझाऊंगा।

String studentName = "Peter Smith"; 

पहली पंक्ति के बाद, एक स्ट्रिंग स्ट्रिंग पूल और एक संदर्भ नाम studentName यह ओर इशारा कर रहा है में बनाया जाता है।

Part1

students[0] = studentName; 

इस बिंदु पर, एक और संदर्भ छात्रों [0] के रूप में नीचे चित्र में दिखाया गया एक ही वस्तु की ओर इशारा करते है। अब 2 संदर्भ स्मृति में बनाए गए उसी ऑब्जेक्ट को इंगित कर रहे हैं।

Part2

studentName = null; 

इस बिंदु के बाद, studentName के संदर्भ शून्य पर अर्थात यह कोई वस्तु की ओर इशारा करते है इंगित करेंगे। लेकिन छात्रों का संदर्भ [0] अभी भी स्ट्रिंग ऑब्जेक्ट (पीटर स्मिथ) को इंगित कर रहा है।

enter image description here

जाहिर तीसरे बयान के बाद, एक संदर्भ शून्य पर इशारा कर रही है, लेकिन एक संदर्भ अभी भी बनाई गई वस्तु की ओर इशारा करते है। इसलिए वस्तु कचरा संग्रह के लिए योग्य नहीं है।

उम्मीद है कि यह मदद करता है।

अद्यतन: क्षमा करें अगर मैंने चर नामों के साथ गड़बड़ की है। लेकिन मुझे उम्मीद है कि आपको विचार मिल जाएगा।

+0

धन्यवाद, महान जवाब! इसकी प्रशंसा करना। एरिक का जवाब स्पॉट पर था (और ट्यूटोरियल में शब्द के रूप में कुछ भ्रम को मंजूरी दे दी), लेकिन मैं इसे भी ऊपर उठा रहा हूं। – cmeeren

+0

@cmeeren: खुशी है कि मैं मदद कर सकता हूं .. :) – thedarkpassenger

1

जहाँ तक मुझे पता है, अपने कोड इस तरह से चलाता है:

  1. String[] students = new String[10]; - बनाएँ students सरणी। students चर अब स्मृति में ऑब्जेक्ट के लिए एक सूचक है।
  2. String studentName = "Peter Smith"; - वैरिएबल "Peter Smith" पर सूचक को असाइन करें। studentName चर में वास्तव में नाम मूल्य नहीं है।
  3. students[0] = studentName; - सूचक को "Peter Smith" मान के लिए सरणी में पहला तत्व असाइन करें।

इस बिंदु दोनों studentName और students[0] पर एक ही बात की ओर इशारा करते हैं, लेकिन उनमें से कोई भी मूल्य में ही होते हैं।

  1. studentName = null; - इस संदर्भ शून्य पर सेट करता है। यह अंतर्निहित स्मृति आवंटन को साफ़ नहीं करता है।
  2. System.out.println(students[0]); - यह Peter Smith प्रिंट करेगा। सरणी में 0 तत्व मूल स्ट्रिंग ऑब्जेक्ट में पॉइंटर होता है।

क्योंकि सरणी अभी भी "Peter Smith" वस्तु का संदर्भ होता है, भले ही मूल सूचक (studentName) null करने के लिए सेट किया गया है, वस्तु कचरा संग्रहण के लिए पात्र नहीं होंगे।


आप जिस तरह से जावा मूल्यों और संकेत संभालती बारे में कुछ और पढ़ना चाहते हैं इन पदों मदद मिल सकती है:

1

सोचो है कि वहाँ एक एक स्मृति क्षेत्र को इंगित करने वाला ऑब्जेक्ट जिसमें "पीटर स्मिथ" है। जब इस ऑब्जेक्ट को सौंपा गया एक अन्य ऑब्जेक्ट यह दूसरा ऑब्जेक्ट भी इस मेमोरी सेल को इंगित कर रहा है। उसके बाद कोई व्यक्ति किसी ऑब्जेक्ट सेल को इंगित न करने वाला पहला ऑब्जेक्ट चाहता है, लेकिन दूसरा अभी भी उसी सेल को इंगित करता है जिसमें अभी भी "पीटर स्मिथ" मूल्य है, इसलिए यही कारण है कि आखिरी पंक्ति नाम प्रिंट करती है। मुझे लगता है कि यह स्पष्ट है कि जेवीएम पहले ऑब्जेक्ट को हटा नहीं सकता है क्योंकि यह अभी भी मूल्यवान है, भले ही दूसरी ऑब्जेक्ट में कोई पॉइंटर पता न हो, फिर भी कोई इसका उपयोग कर रहा है। (ऐसा नहीं है अगर कोई सेकंड किसी पते को इंगित कर रहा हो या नहीं) यह अभी भी किसी अन्य व्यक्ति द्वारा उपयोग में है

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