दिलचस्प पोस्ट
एंड्रॉइड फेसबुक लॉगइन बटन को अनुकूलित करें ब्राउज़र बंद घटना का पता लगाने की कोशिश कर रहा है एसिंक टास्क गतिविधि को नष्ट होने पर भी नहीं रोकेंगे स्विफ्ट: कॉल में अतिरिक्त तर्क 'त्रुटि' गोटो का उपयोग करने में क्या गलत है? Reactjs html में कनवर्ट करें सारणी बनाने में त्रुटि: आपके क्रम के पास आपके एसक्यूएल सिंटैक्स में एक त्रुटि है (ऑर्डर (ऑर्डर_id INT UNSIGNED NOT NULL AUTO_INCREMENT, user_id) लाइन 1 फ़ंक्शन में डिफ़ॉल्ट आर्गमेंट का उपयोग करना नोड में एक फ़ाइल को कैसे जोड़ें? मैं WinForms में किसी चित्र को कैसे घुमाएगा मैं सी # के साथ JSON को पार्स कैसे कर सकता हूं? JS.ParseJSON JSON में एक एकल उद्धरण के कारण "अमान्य JSON" त्रुटि फेंकता है एरो फ़ंक्शन बनाम फ़ंक्शन घोषणा / अभिव्यक्ति: क्या वे बराबर / विनिमेय हैं? सी # में अपवाद कितना महंगा है? लोडिंग के साथ jqgrid reloadGrid को सही पर सेट करें

स्ट्रिंग कॉन्सटेंट पूल

जैसा कि इन स्टैकवॉवरफ्लो प्रश्नों में समझाया गया है: प्रश्न 1 और प्रश्न 2 मैं समझता हूं कि " स्ट्रिंग लीटरलल्स " को इंटर्न दिया जाता है जब:

String s = "abc"; 

और यह कि जेवीएम स्ट्रिंग पूल से मौजूदा एक का उपयोग करने के बजाय एक नया स्ट्रिंग ऑब्जेक्ट बनाएगा जब:

 String s = new String("abc"); 

हालांकि, निम्नलिखित दो समान बयानों को पढ़ने के बाद मुझे संदेह है।

  • एससीजेपी तैयारी पुस्तक से :

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

इस मामले में, हम वास्तव में "नया" कीवर्ड की वजह से थोड़ा अलग व्यवहार करते हैं। ऐसे मामले में, स्ट्रिंग लीटरल्स के संदर्भ अभी भी निरंतर तालिका (स्ट्रिंग लिटरल पूल) में डाल दिए जाते हैं, लेकिन जब आप "नया" कीवर्ड पर आते हैं, तो JVM रन-टाइम पर एक नया स्ट्रिंग ऑब्जेक्ट बनाने के लिए बाध्य है, निरंतर तालिका से एक का उपयोग करने के बजाय

इसलिए यदि हम नॉन-पॉली मेमरी में और पूल मेमोरी में एक संदर्भ डालते हैं, जब हम "नया" का प्रयोग करते हुए एक वस्तु बनाते हैं और ऊपर की परिभाषाओं के आधार पर। जब हम ऐसा करते हैं, तो क्या JVM भी उसी संदर्भ को वापस नहीं लाएगा? :

 String one = new String("test"); String two = "test"; System.out.println(one.equals(two)); // true System.out.println(one == two); // false 

क्योंकि स्ट्रिंग शब्दशः String three = "test"; घोषित करते समय String three = "test"; यह पहले से ही पूल में मौजूद होगा? और इसलिए उसी संदर्भ को वापस करना चाहिए और सही प्रिंट करना चाहिए? या पिछले वक्तव्य का मतलब यह है कि उन्हें पूल मेमोरी में रखा जाएगा, लेकिन जब new ऑपरेटर उपयोग किया जाता है तो उसे छोड़ दिया जाएगा?

वेब के समाधान से एकत्रित समाधान "स्ट्रिंग कॉन्सटेंट पूल"

शायद यह आपकी समझ में सहायता करेगा:

 String literal = "test"; String one = new String(literal); String two = "test"; System.out.println(literal == two); //true System.out.println(one == two); //false 

उदाहरण में आपने पोस्ट किया:

 String one = new String("test"); String two = "test"; 

कंस्ट्रक्टर String(String) को दिया गया संदर्भ, अंतरंग के कारण संदर्भ two के समान है। हालांकि, स्ट्रिंग ही (इन दो संदर्भों से संदर्भित है) का उपयोग एक नया ऑब्जेक्ट बनाने के लिए किया जाता है जिसे one संदर्भ के लिए निर्दिष्ट किया गया है।

इस उदाहरण में, "टेस्ट" मान के साथ बिल्कुल दो String बनाई गई हैं: एक निरंतर पूल में बनाए रखा गया है और जब भी आप एक अभिव्यक्ति में "test" शब्द का प्रयोग करते हैं और "नया" ऑपरेटर द्वारा बनाए गए दूसरे और संदर्भ one को सौंपा

संपादित करें

शायद आप इस कथन के बारे में उलझन में हैं:

जब कंपाइलर एक स्ट्रिंग literal का सामना करता है, यह पूल को देखता है कि क्या एक समान स्ट्रिंग पहले से मौजूद है।

ध्यान दें कि इसे और अधिक स्पष्ट रूप से कहा जा सकता है:

जब कंपाइलर एक स्ट्रिंग literal का सामना करता है, तो यह जांचता है कि क्या पूल में एक समान स्ट्रिंग पहले से मौजूद है

स्ट्रिंग्स केवल पूल में डाल दिए जाते हैं जब उन्हें स्पष्ट रूप से इंटर्न किया जाता है या क्लास द्वारा शाब्दिक उपयोग के लिए इसलिए यदि आपके पास है, उदाहरण के लिए, यह परिदृश्य:

 String te = "te"; String st = "st"; String test = new String(te) + new String(st); 

तब जब String मूल्य test साथ मौजूद होगा, स्ट्रिंग ने पूल में मौजूद नहीं होगा क्योंकि "test" कभी नहीं हुआ है।

  //Creates a new object even if one exists in the pool String s1 = new String("Tendulkar"); // makes a new object string and then the reference is available to the pool String s2 = s1.intern(); //this object is not created but references the address present in the pool String s3 = "Tendulkar"; System.out.print(s1==s2); // results in false System.out.print(s2==s3); //very very true !!! 

"abc" एक ऑब्जेक्ट को लगातार पूल में, कंपाइल / क्लास-लोड टाइम में डालता है , और new String() निष्पादन समय पर एक नई ऑब्जेक्ट बनाता है इसलिए new String("abc") दोनों करता है, लेकिन विभिन्न चरणों में।

आपका प्रश्न :

इसलिए यदि हम नॉन-पॉली मेमरी में और पूल मेमोरी में एक संदर्भ डालते हैं, जब हम "नया" का प्रयोग करते हुए एक वस्तु बनाते हैं और ऊपर की परिभाषाओं के आधार पर। जब हम ऐसा करते हैं तो क्या JVM भी उसी संदर्भ को वापस नहीं लौटाएगा ?:

उत्तर : जब आप नए कीवर्ड का उपयोग करके एक नया स्ट्रिंग ऑब्जेक्ट बनाते हैं, तो उत्पन्न पता एक हेप एड्रेस होगा, स्ट्रिंग निरंतर पूल वाला पता नहीं। और दोनों पते अलग-अलग हैं

प्रश्न :

 String one = new String("test"); String two = "test"; System.out.println(one.equals(two)); // true System.out.println(one == two); // false 

क्या पिछले वक्तव्य का मतलब है कि उन्हें पूल मेमोरी में रखा जाएगा, लेकिन जब नया ऑपरेटर उपयोग किया जाता है तो उसे छोड़ दिया जाएगा?

उत्तर : हाँ, आपकी धारणा सही है जब प्रोग्रामर नए कीवर्ड का उपयोग करता है, तो JVM बस स्ट्रिंग स्टोरीिंग पूल के बारे में अनदेखा करेगा, और हीप में एक नई प्रतिलिपि बनाता है। इसलिए दोनों पते समान नहीं हैं