मुझे जावा में स्ट्रिंग्स की नकल कैसे करनी चाहिए?


199
    String s = "hello";
    String backup_of_s = s;
    s = "bye";

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

लेकिन क्या इस विधि के साथ स्ट्रिंग्स की नकल करना वास्तव में सुरक्षित है (जो नियमित रूप से उत्परिवर्तित वस्तुओं को कॉपी करने के लिए सुरक्षित नहीं है), या इसे लिखना बेहतर है? :

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

दूसरे शब्दों में, इन दो स्निपेट के बीच क्या अंतर है (यदि कोई हो)?


EDIT - पहला स्निपेट सुरक्षित होने का कारण:

मुझे पहले से प्रदान किए गए अच्छे उत्तरों के आधार पर चीजों को थोड़ा और विस्तार से समझाएं, (जो अनिवार्य रूप से 2 स्निपेट के बीच प्रदर्शन के अंतर के सवाल पर केंद्रित थे):

जावा में स्ट्रिंग्स अपरिवर्तनीय हैं, जिसका अर्थ है कि इसके निर्माण के बाद एक स्ट्रिंग ऑब्जेक्ट को संशोधित नहीं किया जा सकता है। अत,

String s = "hello";एक नया स्ट्रिंग उदाहरण बनाता है और इसके पते को बताता है s( sउदाहरण / ऑब्जेक्ट का संदर्भ होने के नाते)

String backup_of_s = s;एक नया चर बनाता है backup_of_sऔर इसे इनिशियलाइज़ करता है ताकि यह वर्तमान में संदर्भित ऑब्जेक्ट को संदर्भित करे s

नोट: स्ट्रिंग अपरिवर्तनीयता गारंटी देती है कि यह ऑब्जेक्ट संशोधित नहीं किया जाएगा: हमारा बैकअप सुरक्षित है

नोट 2: जावा कचरा संग्रहण तंत्र गारंटी देता है कि यह वस्तु तब तक नष्ट नहीं होगी जब तक कि इसे कम से कम एक चर ( backup_of_sइस मामले में) द्वारा संदर्भित किया जाता है

अंत में, s = "bye";एक और स्ट्रिंग उदाहरण बनाता है (अपरिवर्तनीयता के कारण, यह एकमात्र तरीका है), और sचर को संशोधित करता है ताकि यह अब नई वस्तु का संदर्भ दे।

जवाबों:


141

चूंकि तार अपरिवर्तनीय हैं, दोनों संस्करण सुरक्षित हैं। हालांकि, बाद वाला, कम कुशल है (यह एक अतिरिक्त ऑब्जेक्ट बनाता है और कुछ मामलों में चरित्र डेटा की प्रतिलिपि बनाता है)।

इसे ध्यान में रखते हुए, पहले संस्करण को प्राथमिकता दी जानी चाहिए।


15
अपरिवर्तनशीलता का इससे कोई लेना-देना नहीं है। यह सिर्फ यह है कि वस्तु संदर्भ कैसे काम करते हैं। मैं एक बराबर StringBuilder उदाहरण प्रदान कर सकता है।
ग्रिफिएडॉग

1
@BalusC, मैं यह नहीं देख सकता कि नए स्ट्रिंग () JVM के स्ट्रिंग पूल में कुछ भी कैसे बना सकते हैं। केवल स्ट्रिंग लैटरल और इंटर्न () के माध्यम से पूल में आने वाले लोग पूल में हैं।
Snicolas

3
@GriffeyDog: मैं प्रश्न को सचमुच कम पढ़ रहा हूं। मैं जो कह रहा हूं वह यह है कि बिना किसी डर के किसी स्ट्रिंग ऑब्जेक्ट को रेफरेंस देना सुरक्षित है ताकि कोई स्ट्रिंग को संशोधित कर सके।
एनपीई

2
@GriffeyDog मुझे आपकी टिप्पणी बहुत भ्रामक लगती है: अपरिहार्यता वह है जो पहले स्निपेट को सुरक्षित बनाती है, आप यह क्यों कहेंगे कि इसका "इससे" कोई लेना-देना नहीं है?
सेबैस्टियन

5
@ सबस्टियन यह सब sएक अलग वस्तु ( String"अलविदा") को संदर्भित करने के लिए संदर्भ चर को पुन: सौंप रहा है । यह उस संदर्भ चर backup_of_sको प्रभावित नहीं करता है जिसका संदर्भ चर ( String"हैलो") दे रहा है। जैसा मैंने कहा, मैं StringBuilderएस के साथ एक समान उदाहरण प्रदान कर सकता हूं , जो अपरिवर्तनीय नहीं हैं । मेरी टिप्पणी मुख्य रूप से ओपी के बयान के संबंध में है: इस बिंदु पर, बैकअप चर में अभी भी मूल मूल्य "हैलो" है (यह स्ट्रिंग के अपरिवर्तनीय अधिकार के कारण है?)।
ग्रिफिएडॉग

22

तार अपरिवर्तनीय वस्तुएं हैं, ताकि आप उन्हें केवल उनके संदर्भ का मुकाबला करने के लिए कॉपी कर सकें, क्योंकि संदर्भित वस्तु बदल नहीं सकती है ...

तो आप किसी भी समस्या के बिना अपने पहले उदाहरण में कॉपी कर सकते हैं:

String s = "hello";
String backup_of_s = s;
s = "bye";

10

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

अपरिवर्तनीयता का अर्थ है कि आपका पहला संस्करण आपकी अपेक्षा के अनुरूप व्यवहार करता है और इस तरह से पसंदीदा होना चाहिए।


0

स्ट्रिंग पूल के संदर्भ में दूसरा मामला भी अक्षम है, आपको इसे आंतरिक बनाने के लिए रिटर्न संदर्भ पर स्पष्ट रूप से इंटर्न () को कॉल करना होगा।


-16
String str1="this is a string";
String str2=str1.clone();

इस तरह की नकल के बारे में कैसे? मुझे लगता है कि एक नई प्रति प्राप्त करना बेहतर है, ताकि संदर्भ और वायदा कार्रवाई में संशोधित str1होने पर डेटा प्रभावित न हो str2


3
Stringअपरिवर्तनीय है। क्लोनिंग स्ट्रिंग्स का कोई मतलब नहीं है।
व्लादिमीर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.